Go里面有兩個保留的函數(shù):init函數(shù)(能夠應(yīng)用于所有的package)和main函數(shù)(只能應(yīng)用于package main)。這兩個函數(shù)在定義時不能有任何的參數(shù)和返回值。
雖然一個package里面可以寫任意多個init函數(shù),但這無論是對于可讀性還是以后的可維護(hù)性來說,我們都強烈建議用戶在一個package中每個文件只寫一個init函數(shù)。
Go程序會自動調(diào)用init()和main(),所以你不需要在任何地方調(diào)用這兩個函數(shù)。每個package中的init函數(shù)都是可選的,但package main就必須包含一個main函數(shù)。
程序的初始化和執(zhí)行都起始于main包。如果main包還導(dǎo)入了其它的包,那么就會在編譯時將它們依次導(dǎo)入。有時一個包會被多個包同時導(dǎo)入,那么它只會被導(dǎo)入一次(例如很多包可能都會用到fmt包,但它只會被導(dǎo)入一次,因為沒有必要導(dǎo)入多次)。當(dāng)一個包被導(dǎo)入時,如果該包還導(dǎo)入了其它的包,那么會先將其它包導(dǎo)入進(jìn)來,然后再對這些包中的包級常量和變量進(jìn)行初始化,接著執(zhí)行init函數(shù)(如果有的話),依次類推。等所有被導(dǎo)入的包都加載完畢了,就會開始對main包中的包級常量和變量進(jìn)行初始化,然后執(zhí)行main包中的init函數(shù)(如果存在的話),最后執(zhí)行main函數(shù)。
下圖詳細(xì)地解釋了整個執(zhí)行過程:

main函數(shù)引入包初始化流程圖