天天看點

Go基礎:路徑、檔案名和包名的關系Go 包的概念Go 包 的特征結論

Go 包的概念

  1. 把相同的功能放到一個目錄,稱之為包
  2. 包可以被其他的包引用
  3. main包用來生成可執行檔案,每個程式隻有一個main包
  4. 包可以提高代碼的可複用性

Go 包 的特征

一個檔案夾下隻能有一個package。

  • import後面的其實是GOPATH開始的相對目錄路徑,包括最後一段。但由于一個目錄下隻能有一個package,是以import一個路徑就等于是import了這個路徑下的包。
  • 注意,這裡指的是“直接包含”的go檔案。如果有子目錄,那麼子目錄的父目錄是完全兩個包。
    • 比如你實作了一個電腦package,名叫calc,位于calc目錄下;但又想給别人一個使用範例,于是在calc下可以建個example子目錄(calc/example/),這個子目錄裡有個example.go(calc/example/example.go)。此時,example.go可以是main包,裡面還可以有個main函數。

一個package的檔案不能在多個檔案夾下。

在 Golang 的文檔中,Language Specification 頁面,Package clause 下,指明了

A set of files sharing the same PackageName form the implementation of a package. An implementation may require that all source files for a package inhabit the same directory.

也就是說,一個包所有的檔案,必須位于同一個目錄下

  • 如果多個檔案夾下有重名的package,它們其實是彼此無關的package。
  • 如果一個go檔案需要同時使用不同目錄下的同名package,需要在import這些目錄時為每個目錄指定一個package的别名。

包名自然可以和檔案夾名不一樣,畢竟一個是導入路徑,一個是包名

但不建議這麼做,這樣容易造成調用這個包的人,無法快速知道這個包的名稱是什麼

至于為什麼不用目錄名作為包名,我想也正如大家所說,為了避免目錄中出現奇怪的字元,也為了調用者友善使用

在 Golang 的文檔中, Language Specification 頁面,Import declarations 下,有這樣的說明

Go 語言規範官方文檔 中有對

PackageName

ImportPath

的具體描述:
ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec       = [ "." | PackageName ] ImportPath .
ImportPath       = string_lit .      
Go基礎:路徑、檔案名和包名的關系Go 包的概念Go 包 的特征結論

The PackageName is used in qualified identifiers to access exported identifiers of the package within the importing source file. It is declared in the file block. If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package. If an explicit period (.) appears instead of a name, all the package’s exported identifiers declared in that package’s package block will be declared in the importing source file’s file block and must be accessed without a qualifier.

也就是說,在執行導入的時候,若不手動定義包名,則從導入路徑的源碼檔案中的 package 行擷取包名,也即目錄名和包名沒有直接的關系。

結論

1、import 導入的參數是路徑,而非包名。

2、盡管習慣将包名和目錄名保證一緻,但這不是強制規定;

3、在代碼中引用包成員時,使用包名而非目錄名;

4、同一目錄下,所有源檔案必須使用相同的包名稱(因為導入時使用絕對路徑,是以在搜尋路徑下,包必須有唯一路徑,但無須是唯一名字);

5、至于檔案名,更沒啥限制(擴充名為.go);