golang語言 包、模塊


go語言101,對引用路徑作了比較詳細的解釋

 

一個代碼包可以由若干Go源文件組成。一個代碼包的源文件須都處於同一個目錄下。 一個目錄(不包含子目錄)下的所有源文件必須都處於同一個代碼包中,亦即這些源文件開頭的package pkgname語句必須一致。 所以,一個代碼包對應着一個目錄(不包含子目錄),反之亦然。 對應着一個代碼包的目錄稱為此代碼包的目錄。 一個代碼包目錄下的每個子目錄對應的都是另外一個獨立的代碼包。

對於官方Go SDK來說,一個引入路徑中包含有internal目錄名的代碼包被視為一個特殊的代碼包。 它只能被此internal目錄的直接父目錄中的代碼包所引入。 比如,代碼包.../a/b/c/internal/d/e/f.../a/b/c/internal只能被引入路徑含有.../a/b/c前綴的代碼包引入。

根據不同的情形,名稱為vendor的目錄也可能被視為特殊的代碼包目錄。下面的段落將會解釋哪些vendor目錄將被視為特殊的目錄。

Go SDK 1.11版本引入了模塊(modules)特性的概念。 一個模塊可以被看做是一些擁有一個共同的根目錄的代碼包集合,即一個代碼包樹。 每個模塊關聯着一個根引入路徑和一個語義化版本號 語義化版本號的主版本須體現在根引入路徑中,除了v0v1主版本號。 兩個關聯着不同的根引入路徑的模塊被視為兩個不同的模塊。

 

包不能循環依賴,模塊可以循環依賴

包的名稱和目錄一般是相同的,引入的是包的目錄,使用的是包的名稱 待驗證

 

 

一個包可能包含多個init()函數,他們的執行順序不確定,init()不能被顯式調用,init()在變量初始化完成后被調用,串行執行,只被執行一遍

go的構建工具將.go文件按文件名排序,然后依次調用編譯器編譯。

導入的包會在當前包之前被初始化,多次導入相同的包,該包只會初始化一次

一個約定就是包名應為其源碼目錄的基本名稱。在 src/pkg/encoding/base64 中的包應作為 "encoding/base64" 導入,其包名應為 base64, 而非 encoding_base64 或 encodingBase64。

 

 p 導入了包 q,則 q 的 init 函數會在 p 的任何函數啟動前完成。

函數 main.main 會在所有的 init 函數結束后啟動。

 

一個程序中所涉及到的所有的在運行時刻要用到的代碼包的加載是串行執行的。 在一個程序啟動時,每個包中總是在它所有依賴的包都加載完成之后才開始加載。 程序代碼包總是最后一個被加載的代碼包。每個被用到的包會被而且僅會被加載一次。

在加載一個代碼包的過程中,所有的聲明在此包中的init函數將被串行調用並且僅調用執行一次。 一個代碼包中聲明的init函數的調用肯定晚於此代碼包所依賴的代碼包中聲明的init函數。 所有的init函數都將在調用main入口函數之前被調用執行。

在同一個源文件中聲明的init函數將按從上到下的順序被調用執行。 對於聲明在同一個包中的兩個不同源文件中的兩個init函數,Go語言白皮書推薦(但不強求)按照它們所處於的源文件的名稱的詞典序列(對英文來說,即字母順序)來調用。 所以最好不要讓聲明在同一個包中的兩個不同源文件中的兩個init函數存在依賴關系。

在加載一個代碼包的時候,此代碼包中聲明的所有包級變量都將在此包中的任何一個init函數執行之前初始化完畢。

 

導入的包可以以空行進行分組,gofmt和goimports等工具,可以把組內的包獨立排序

import mrand "math/rand" // 重命名,在當前文件里有效

import _ "math/rand" // 匿名導入

import . "fmt" // 可以直接使用 Printf(...)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM