go語(yǔ)言中init函數(shù)用于包(package)的初始化,該函數(shù)是go語(yǔ)言的一個(gè)重要特性哼丈,有下面的特征:
1 init函數(shù)是用于程序執(zhí)行前做包的初始化的函數(shù)臣樱,比如初始化包里的變量等
2 每個(gè)包可以擁有多個(gè)init函數(shù)
3 包的每個(gè)源文件也可以擁有多個(gè)init函數(shù)
4 同一個(gè)包中多個(gè)init函數(shù)的執(zhí)行順序go語(yǔ)言沒(méi)有明確的定義
5 不同包的init函數(shù)按照包導(dǎo)入的依賴(lài)關(guān)系決定該初始化函數(shù)的執(zhí)行順序
6 init函數(shù)不能被其他函數(shù)調(diào)用,而是在main函數(shù)執(zhí)行之前再膳,自動(dòng)被調(diào)用
包的初始化
為了使用導(dǎo)入的包挺勿,首先必須將其初始化。初始化總是以單線(xiàn)程執(zhí)行喂柒,并且按照包的依賴(lài)關(guān)系順序執(zhí)行不瓶。這通過(guò)Golang的運(yùn)行時(shí)系統(tǒng)控制,如下圖所示:
- 初始化導(dǎo)入的包(遞歸導(dǎo)入)
- 對(duì)包塊中聲明的變量進(jìn)行計(jì)算和分配初始值
-
執(zhí)行包中的init函數(shù)
image.png
下面二個(gè)文件進(jìn)行演示:
main.go
package main
import (
"fmt"
)
var _ int64 = cc()
func init() {
fmt.Println("main.init1")
}
func init() {
fmt.Println("main. init2")
}
func cc() int64 {
fmt.Println("calling cc() in main.go")
return 1
}
func main() {
fmt.Println("main.ing")
}
ap.go
package main
import "fmt"
func init() {
fmt.Println("ap.init1")
}
func init() {
fmt.Println("ap.init2")
}
執(zhí)行 go build ap.go main.go胳喷,編譯之后執(zhí)行./main:
calling cc() in main.go
main.init1
main. init2
ap.init1
ap.init2
main.ing
可以得出的是:
1 一個(gè)package或者是go文件可以包含多個(gè)init函數(shù)湃番,
2 init函數(shù)是在main函數(shù)之前執(zhí)行的,
3 init函數(shù)被自動(dòng)調(diào)用吭露,不能在其他函數(shù)中調(diào)用吠撮,顯式調(diào)用會(huì)報(bào)該函數(shù)未定義
執(zhí)行順序:解析變量 > init 函數(shù) > main 函數(shù)