在go語言中,init()方法用于包的初始化;初始化每個(gè)包后,會自動(dòng)執(zhí)行init()函數(shù),并且執(zhí)行優(yōu)先級高于主函數(shù)的執(zhí)行優(yōu)先級。init()方法通常用于:1、變量初始化;2、檢查/修復(fù)狀態(tài);3、注冊器;4、運(yùn)行計(jì)算。init()函數(shù)在程序運(yùn)行時(shí),自動(dòng)自動(dòng)被調(diào)用執(zhí)行,不能在代碼中主動(dòng)調(diào)用它。不同包的init函數(shù)按照包導(dǎo)入的依賴關(guān)系決定該初始化函數(shù)的執(zhí)行順序。
本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。
Go init函數(shù)的詳細(xì)說明
go語言中init函數(shù)用于包(package)的初始化,該函數(shù)是go語言的一個(gè)重要特性
程序執(zhí)行時(shí)導(dǎo)入包語句會自動(dòng)觸發(fā)包內(nèi)部init()函數(shù)的調(diào)用。
初始化每個(gè)包后,會自動(dòng)執(zhí)行init()函數(shù),并且執(zhí)行優(yōu)先級高于主函數(shù)的執(zhí)行優(yōu)先級。
需要注意的是:init()函數(shù)沒有參數(shù),也沒有返回值。
init函數(shù)通常用于:
- 變量初始化
- 檢查/修復(fù)狀態(tài)
- 注冊器
-
運(yùn)行計(jì)算
init()函數(shù)在程序運(yùn)行時(shí),自動(dòng)自動(dòng)被調(diào)用執(zhí)行,不能在代碼中主動(dòng)調(diào)用它。
包初始化執(zhí)行的順序如下圖所示:
結(jié)果是:
10 Hello 沙河
init()函數(shù)有下面的特點(diǎn):
-
init函數(shù)是用于程序執(zhí)行前做包的初始化的函數(shù),比如初始化包里的變量等
-
每個(gè)包可以擁有多個(gè)init函數(shù)
-
包的每個(gè)源文件也可以擁有多個(gè)init函數(shù)
-
同一個(gè)包中多個(gè)init函數(shù)的執(zhí)行順序go語言沒有明確的定義(說明)
-
不同包的init函數(shù)按照包導(dǎo)入的依賴關(guān)系決定該初始化函數(shù)的執(zhí)行順序
-
init函數(shù)不能被其他函數(shù)調(diào)用,而是在main函數(shù)執(zhí)行之前,自動(dòng)被調(diào)用
包初始化
為了使用導(dǎo)入的程序包,必須首先對其進(jìn)行初始化。初始化始終在單個(gè)線程中執(zhí)行,并且以程序包依賴關(guān)系的順序執(zhí)行。這由Golang的運(yùn)行時(shí)系統(tǒng)控制,如下圖所示:
- 初始化導(dǎo)入的包(遞歸導(dǎo)入)
- 計(jì)算并為塊中聲明的變量分配初始值
- 在包中執(zhí)行初始化函數(shù)
initial.go
package main import "fmt" var _ int64=s() func init(){ fmt.Println("init function --->") } func s() int64{ fmt.Println("function s() --->") return 1 } func main(){ fmt.Println("main --->") }
執(zhí)行結(jié)果
function s() —> init function —> main —>
即使程序包被多次導(dǎo)入,初始化也只需要一次。
特性介紹
init函數(shù)不需要傳入?yún)?shù),也不需要返回任何值。與main相比,init沒有聲明,因此無法引用。
package main import "fmt" func init(){ fmt.Println("init") } func main(){ init() }
編譯上述函數(shù)“undefined:init
”時(shí)發(fā)生錯(cuò)誤。
每個(gè)源文件可以包含一個(gè)以上的init函數(shù),請記住,寫在每個(gè)源文件中的“行進(jìn)方式”只能包含一個(gè)init函數(shù),這有點(diǎn)不同,因此進(jìn)行下一個(gè)驗(yàn)證。
package main import "fmt" func init(){ fmt.Println("init 1") } func init(){ fmt.Println("init2") } func main(){ fmt.Println("main") } /* 實(shí)施結(jié)果: init1 init2 main */
從上面的示例中,您可以看到每個(gè)源文件可以包含多個(gè)init函數(shù)。
初始化函數(shù)的一個(gè)常見示例是設(shè)置初始表達(dá)式的值。
var precomputed=[20]float64{} func init(){ var current float64=1 precomputed[0]=current for i:=1;i<len(precomputed);i++{ precomputed[i]=precomputed[i-1]*1.2 } }
因?yàn)椴豢赡茉谏厦娴拇a(這是一條語句)中將for循環(huán)用作預(yù)先計(jì)算的值,所以可以使用init函數(shù)來解決此問題。
Go套件匯入規(guī)則的副作用
Go非常嚴(yán)格,不允許引用未使用的軟件包。但是有時(shí)您引用包只是為了調(diào)用init函數(shù)進(jìn)行一些初始化??諛?biāo)識符(即下劃線)的目的是解決此問題。
import _ "image/png"
【