導入包:
- 標準包使用的是給定的短路徑,如"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函數。下圖詳細地解釋了整個執行過程:html
注意:
import 導入 Go 包有幾種方式,用途不一樣。 代碼統一存儲在工做目錄下,工做目錄裏邊會有不少個包,不一樣包按目錄組織,包下面由多個代碼文件組成。導入包時按包的惟一路徑進行導入,導入的包默認是必需要使用,若是不使用則編譯失敗,須要移除,減小沒必要要代碼的引入,固然還有其餘使用場景。默認狀況下,咱們使用文件名作爲包名,方便理解。不一樣包組織不一樣的功能實現,方便理解。golang
編譯時使用的是包源碼仍是.a?
一個非main包在編譯後會生成一個.a文件(在臨時目錄下生成,除非使用go install安裝到$GOROOT或$GOPATH下,不然你看不到.a),用於後續可執行程序連接使用。好比Go標準庫中的包對應的源碼部分路徑在:$GOROOT/src,而標準庫中包編譯後的.a文件路徑在$GOROOT/pkg/darwin_amd64下。一個奇怪的問題在我腦殼中升騰起來,編譯時,編譯器到底用的是.a仍是源碼?sql
- 在使用第三方包的時候,當源碼和.a均已安裝的狀況下,編譯器連接的是源碼。而所謂的使用第三方包源碼,其實是連接了以該最新源碼編譯的臨時目錄下的.a文件而已。
- Go標準庫中的包也是這樣麼?對於標準庫,好比fmt而言,編譯時,到底使用的時$GOROOT/src下源碼仍是$GOROOT/pkg下已經編譯好的.a呢?不過與自定義包不一樣的是,即使你修改了fmt包的源碼(未從新編譯GO安裝包),用戶源碼編譯時,也不會嘗試從新編譯fmt包的,依舊只是在連接時連接已經編譯好的fmt.a
Go語言中import後面路徑中最後的一個元素究竟是包名仍是路徑名?
- import後面的最後一個元素應該是路徑,就是目錄,並不是包名。可是不少時候,這個路徑名字和包名字相同
- import m "lib/math" m指代的是lib/math路徑下惟一的那個包 ,編譯器在這個路徑下若是發現了兩個包,是不容許的,編譯報錯
一、https://yushuangqi.com/blog/2016/understanding-golang-import-package.html函數
二、https://blog.csdn.net/zhangzhebjut/article/details/25564457spa
三、https://tonybai.com/2015/03/09/understanding-import-packages/.net