導入包:
- 標准包使用的是給定的短路徑,如"fmt"、"net/http"
- 自己的包,需要在工作目錄(GOPATH)下指定一個目錄,improt 導入包,實際上就是基於工作目錄的文件夾目錄
導入包的多種方式:
- 直接根據$GOPATH/src目錄導入import "test/lib"(路徑其實是$GOPATH/src/test/lib)
- 別名導入:import alias_name "test/lib" ,這樣使用的時候,可以直接使用別名
- 使用點號導入:import . "test/lib",作用是使用的時候直接省略包名
- 使用下划線導入:improt _ "test/lib",該操作其實只是引入該包。當導入一個包時,它所有的init()函數就會被執行,但有些時候並非真的需要使用這些包,僅僅是希望它的init()函數被執行而已。這個時候就可以使用_操作引用該包。即使用_操作引用包是無法通過包名來調用包中的導出函數,而是只是為了簡單的調用其init函數()。往往這些init函數里面是注冊自己包里面的引擎,讓外部可以方便的使用,例如實現database/sql的包,在init函數里面都是調用了sql.Register(name string, driver driver.Driver)注冊自己,然后外部就可以使用了。
- 相對路徑導入 import "./model" //當前文件同一目錄的model目錄,但是不建議這種方式import
包的導入過程說明:
程序的初始化和執行都起始於main包。如果main包還導入了其它的包,那么就會在編譯時將它們依次導入。有時一個包會被多個包同時導入,那么它只會被導入一次(例如很多包可能都會用到fmt包,但它只會被導入一次,因為沒有必要導入多次)。當一個包被導入時,如果該包還導入了其它的包,那么會先將其它包導入進來,然后再對這些包中的包級常量和變量進行初始化,接着執行init函數(如果有的話),依次類推。等所有被導入的包都加載完畢了,就會開始對main包中的包級常量和變量進行初始化,然后執行main包中的init函數(如果存在的話),最后執行main函數。下圖詳細地解釋了整個執行過程:

注意:
import 導入 Go 包有幾種方式,用途不同。 代碼統一存儲在工作目錄下,工作目錄里邊會有很多個包,不同包按目錄組織,包下面由多個代碼文件組成。導入包時按包的唯一路徑進行導入,導入的包默認是必須要使用,如果不使用則編譯失敗,需要移除,減少不必要代碼的引入,當然還有其他使用場景。默認情況下,我們使用文件名做為包名,方便理解。不同包組織不同的功能實現,方便理解。
編譯時使用的是包源碼還是.a?
一個非main包在編譯后會生成一個.a文件(在臨時目錄下生成,除非使用go install安裝到$GOROOT或$GOPATH下,否則你看不到.a),用於后續可執行程序鏈接使用。比如Go標准庫中的包對應的源碼部分路徑在:$GOROOT/src,而標准庫中包編譯后的.a文件路徑在$GOROOT/pkg/darwin_amd64下。一個奇怪的問題在我腦袋中升騰起來,編譯時,編譯器到底用的是.a還是源碼?
- 在使用第三方包的時候,當源碼和.a均已安裝的情況下,編譯器鏈接的是源碼。而所謂的使用第三方包源碼,實際上是鏈接了以該最新源碼編譯的臨時目錄下的.a文件而已。
- Go標准庫中的包也是這樣么?對於標准庫,比如fmt而言,編譯時,到底使用的時$GOROOT/src下源碼還是$GOROOT/pkg下已經編譯好的.a呢?不過與自定義包不同的是,即便你修改了fmt包的源碼(未重新編譯GO安裝包),用戶源碼編譯時,也不會嘗試重新編譯fmt包的,依舊只是在鏈接時鏈接已經編譯好的fmt.a
Go語言中import后面路徑中最后的一個元素到底是包名還是路徑名?
- import后面的最后一個元素應該是路徑,就是目錄,並非包名。但是很多時候,這個路徑名字和包名字相同
- import m "lib/math" m指代的是lib/math路徑下唯一的那個包 ,編譯器在這個路徑下如果發現了兩個包,是不允許的,編譯報錯
1、https://yushuangqi.com/blog/2016/understanding-golang-import-package.html
2、https://blog.csdn.net/zhangzhebjut/article/details/25564457
3、https://tonybai.com/2015/03/09/understanding-import-packages/
