go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性,有下面的特征:
1 init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
2 每个包可以拥有多个init函数
3 包的每个源文件也可以拥有多个init函数
4 同一个包中多个init函数的执行顺序go语言没有明确的定义
5 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
6 init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
包的初始化
为了使用导入的包,首先必须将其初始化。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。这通过Golang的运行时系统控制,如下图所示:
- 初始化导入的包(递归导入)
- 对包块中声明的变量进行计算和分配初始值
-
执行包中的init函数
下面二个文件进行演示:
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")
}
执行 go build ap.go main.go,编译之后执行./main:
calling cc() in main.go
main.init1
main. init2
ap.init1
ap.init2
main.ing
可以得出的是:
1 一个package或者是go文件可以包含多个init函数,
2 init函数是在main函数之前执行的,
3 init函数被自动调用,不能在其他函数中调用,显式调用会报该函数未定义
执行顺序:解析变量 > init 函数 > main 函数