在一個 go 程序中一般包含:包、常量、變量、init()、main()等元素,若是同時存在多個包,包之間存在依賴關係,每一個包中存在多個 init 函數,每一個文件中存在多個 init 函數。函數
包的執行順序
- 在 main 包中的 go 文件默認老是會被執行
- 同包下的不一樣 go 文件,按照文件名「從小到大」排序順序執行
- 其餘的包只有被 main 包 import 纔會執行,按照 import 的前後順序執行
- 被遞歸 import 的包的初始化順序與 import 順序相反,例如:導入順序 main –> A –> B –> C,則初始化順序爲 C –> B –> A –> main
- 一個包被其它多個包 import,但只能被初始化一次
- main 包老是被最後一個初始化,由於它老是依賴別的包
- 避免出現循環 import,例如:A –> B –> C –> A
go 程序的初始化順序見下圖:blog
init 和 main 函數
init()、main() 是 go 語言中的保留函數,兩個函數在 go 語言中的區別以下:
相同點:排序
- 兩個函數在定義時不能有任何的參數和返回值
- 該函數只能由 go 程序自動調用,不能夠被引用
不一樣點:遞歸
- init 能夠應用於任意包中,且能夠重複定義多個。
- main 函數只能用於 main 包中,且只能定義一個。
兩個函數的執行順序:字符串
- 對同一個 go 文件的 init( ) 調用順序是從上到下的
- 對同一個 package 中的不一樣文件,將文件名按字符串進行「從小到大」排序,以後順序調用各文件中的init()函數
- 對於不一樣的 package,若是不相互依賴的話,按照 main 包中 import 的順序調用其包中的 init() 函數
- 若是 package 存在依賴,調用順序爲最後被依賴的最早被初始化,例如:導入順序 main –> A –> B –> C,則初始化順序爲 C –> B –> A –> main,一次執行對應的 init 方法。
常量、變量、init()、main()
在同一個文件中,常量、變量、init()、main() 依次進行初始化。it
init 順序
一、在同一個 package 中,能夠多個文件中定義 init 方法import
二、在同一個 go 文件中,能夠重複定義 init 方法變量
三、在同一個 package 中,不一樣文件中的 init 方法的執行按照文件名前後執行各個文件中的 init 方法循環
四、在同一個文件中的多個 init 方法,按照在代碼中編寫的順序依次執行不一樣的 init 方法引用
五、對於不一樣的 package,若是不相互依賴的話,按照 main 包中 import 的順序調用其包中的 init() 函數
六、若是 package 存在依賴,調用順序爲最後被依賴的最早被初始化,例如:導入順序 main –> A –> B –> C,則初始化順序爲 C –> B –> A –> main,一次執行對應的 init 方法。
全部 init 函數都在同⼀個 goroutine 內執⾏。 全部 init 函數結束後纔會執⾏ main.main 函數。