2014-06-20 34 views
10

Tôi đã cố gắng hiểu cách gói hoạt động tốt hơn về những gì golang thực thi hơn là những gì thường được thực hiện hoặc được coi là thực hành tốt (chúng ta có thể nói về thực hành tốt sau này, nhưng tôi ước để hiểu đầu tiên).Làm thế nào để các gói hoạt động trong golang

Từ effective go nó nói:

"ước khác là tên gói là tên cơ sở của thư mục nguồn của nó ..."

Tuy nhiên, mô tả ở trên dường như không bị buộc phải đi hoặc yêu cầu. Vì vậy, tôi đã tự hỏi, nếu tôi được phép có các tệp nhiều khác nhau với khác nhau tờ khai gói ở trên cùng trong số cùng một cơ sở thư mục. Nếu tôi được phép khai báo nhiều gói trong cùng một thư mục, làm cách nào để nhập chúng và sử dụng từng tệp riêng lẻ trong cùng một tệp? Về cơ bản, tôi đoán một trong những vấn đề tôi có là do từ ngữ của một số hướng dẫn/tài liệu đi. Nếu nó là theo quy ước, thì đối với tôi, nó ngụ ý rằng nó là KHÔNG được thi hành bởi ngôn ngữ. Bởi vì ví dụ, hãy lập trình viên KHÔNG viết từ khóa func cho một hàm theo quy ước. Chúng tôi viết func bởi vì nếu không, bạn sẽ hét lên với bạn và nó sẽ không biên dịch. Vì vậy, tôi muốn làm rõ điều này với ví dụ dưới đây (và nếu có thể thay đổi tài liệu cho đi, bởi vì đây là một vấn đề lớn trong quan điểm của tôi, làm thế nào điều này có thể được thực hiện?).

Ví dụ nói rằng tôi có ba tập tin A.go, B.go, C.go đó in một chức năng in Print() mà chỉ đơn giản in a, b, c tương ứng. Tất cả chúng đều nằm trong cùng một thư mục cơ sở có tên là base. Sau đó, mỗi tờ khai có một tờ khai khác nhau package Apkg, package Bpkg, package Cpkg.

sau đó bạn sẽ nhập và nhập chúng như thế nào? Có cái gì đó như sau công việc?

package main 

import(
    nameA "github.com/user_me/base/Apkg" 
    nameB "github.com/user_me/base/Bpkg" 
    nameC "github.com/user_me/base/Cpkg" 
) 

func main() { 
    nameA.Print() \\prints a 
    nameB.Print() \\prints b 
    nameC.Print() \\prints c 
} 

hoặc có lẽ chúng ta thậm chí không cần phải xác định tên nếu statments gói là hàng đầu đã khác nhau:

package main 

import(
    "github.com/user_me/base" 
) 

func main() { 
    Apkg.Print() \\prints a 
    Bpkg.Print() \\prints b 
    Cpkg.Print() \\prints c 
} 

file in ấn là:

A.go:

//file at github.com.user_me/base and name A.go 
package Apkg 

import "fmt" 

func Print(){ 
    fmt.Println("A") 
} 

B.go:

//file at github.com.user_me/base and name B.go 
package Bpkg 

import "fmt" 

func Print(){ 
    fmt.Println("B") 
} 

C.go: // tập tin tại github.com.user_me/cơ sở và tên C.go gói Cpkg

import "fmt" 

func Print(){ 
    fmt.Println("C") 
} 

Ngoài ra, nếu bạn có thể có một cái tên khác nhau từ base , ai đó có thể làm rõ cho tôi cách nhập thực sự được thực hiện? Nếu tên gói là package Apkg trong cơ sở thì việc nhập phải là import github.com/user_me/base hoặc import github.com/user_me/base/Apkg hoặc github.com/user_me/Apkg.

Tôi chưa thử nghiệm điều này nhưng tôi sẽ sớm thực hiện việc này.Hợp đồng nhập khẩu trong thời gian đi đã hơi khó hiểu đối với tôi và rất muốn nhận được câu trả lời và chia sẻ nó với thế giới.

Trả lời

7

Không, đó là 1 gói cho mỗi thư mục, vì vậy bạn sẽ cần phải có họ:

$GOPATH/src/github.com/user_me/base/Apkg/a.go 
$GOPATH/src/github.com/user_me/base/Bpkg/b.go 
$GOPATH/src/github.com/user_me/base/Cpkg/c.go 

Bạn thậm chí không thể xây dựng nó bằng cách khác:

┌─ [email protected] [/t/blah]                           
└──➜ go build 
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah 

tên gói của bạn của bạn không cần phải có cùng tên với thư mục họ đang ở, tuy nhiên tất cả các tệp trong một thư mục phải có cùng tên gói.

Ngoài ra, bạn có thể đổi tên gói nhập khẩu, ví dụ:

import (
    cr "crypto/rand" 
    mr "math/rand" 
) 

Hoặc thư viện của bạn được gọi là chính (ý tưởng tồi btw):

import m "github.com/user_me/base/main" 
+0

Vì vậy, nó không tốt "ước", các ngôn ngữ thực thi nó? –

+0

Yep, ví dụ như kiểm tra cập nhật – OneOfOne

+0

Thú vị là chúng cụm từ nó theo cách kỳ lạ như vậy bằng cách nói "quy ước" của nó nếu ngôn ngữ thực thi nó. Lý do tôi hoài nghi và bối rối về điều này là bởi vì trước đây, tôi đã có một tên gói ở đầu các tệp của tôi cho 'base' không khớp với tên thư mục cơ sở. Vì vậy, ví dụ, tôi đã 'gói superBase' thay vì' gói base' và tôi vẫn có thể chạy 'go test' mặc dù nhập của tôi là' import baseName github.com/user_me/base' nhưng gói cho mỗi tệp là 'gói superBase'. Kỳ dị. Đây có phải là một điều đặc biệt về 'thử nghiệm' không? –

Các vấn đề liên quan