您好,登錄后才能下訂單哦!
golang中導入包的方式有哪些?針對這個問題,這篇文章給出了相對應的分析和解答,希望能幫助更多想解決這個問題的朋友找到更加簡單易行的辦法。
Go語言是使用包來組織源代碼的,包(package)是多個 Go 源碼的集合,是一種高級的代碼復用方案。Go語言中為我們提供了很多內置包,如 fmt、os、io 等。
任何源代碼文件必須屬于某個包,同時源碼文件的第一行有效代碼必須是package pacakgeName 語句,通過該語句聲明自己所在的包。
Go語言的包借助了目錄樹的組織形式,一般包的名稱就是其源文件所在目錄的名稱,雖然Go語言沒有強制要求包名必須和其所在的目錄名同名,但還是建議包名和所在目錄同名,這樣結構更清晰。
包可以定義在很深的目錄中,包名的定義是不包括目錄路徑的,但是包在引用時一般使用全路徑引用。比如在GOPATH/src/a/b/ 下定義一個包 c。在包 c 的源碼中只需聲明為package c,而不是聲明為package a/b/c,但是在導入 c 包時,需要帶上路徑,例如import "a/b/c"。
導入包:
標準包使用的是給定的短路徑,如"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包有幾種方式,用途不同。 代碼統一存儲在工作目錄下,工作目錄里邊會有很多個包,不同包按目錄組織,包下面由多個代碼文件組成。導入包時按包的唯一路徑進行導入,導入的包默認是必須要使用,如果不使用則編譯失敗,需要移除,減少不必要代碼的引入,當然還有其他使用場景。默認情況下,我們使用文件名做為包名,方便理解。不同包組織不同的功能實現,方便理解。
Go語言中import后面路徑中最后的一個元素到底是包名還是路徑名?
import后面的最后一個元素應該是路徑,就是目錄,并非包名。但是很多時候,這個路徑名字和包名字相同
import m "lib/math" m指代的是lib/math路徑下唯一的那個包 ,編譯器在這個路徑下如果發現了兩個包,是不允許的,編譯報錯。
編譯時使用的是包源碼還是.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
關于golang中導入包的方式就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。