Go语言的初始化顺序,包,变量,init
目录结构:
$ tree
.
├── a.go
├── p1
│ └── p1.go
└── testinit.go
1 directory, 3 files
p1.go
代码如下:
package p1
import "fmt"
var x float32 = 1.2 //1.2
func init() { // 1.3
fmt.Printf("p1 package, x:%f\n", x) // 1.4
}
func DoNothing() {
fmt.Println("do nothing. \n")
}
a.go
代码:
package main
import "fmt"
var WhatIsThe1 = AnswerToLife(2.1) //2.1
var WhatIsThe2 = AnswerToLife(2.2) //2.2
var WhatIsThe3 = AnswerToLife(2.3) //2.3
func init() { //3.1
fmt.Printf("init WhatIsThe in a.go `s init 3.1:%d\n", 2)
}
func init() { //3.2
fmt.Printf("init WhatIsThe in a.go`s init 3.2:%d\n",3)
}
testinit.go
代码:
package main
import (
"demo/demo2/p1"
"fmt"
)
var WhatIsThe4 = AnswerToLife(2.4) //2.4
var WhatIsThe5 = AnswerToLife(2.5) //2.5
var WhatIsThe6 = AnswerToLife(2.6) //2.6
func AnswerToLife(index float32) float32 {
fmt.Printf("init package level variable, WhatIsThe: %f\n", index)
return index
}
func init() { //3.3
fmt.Printf("init WhatIsThe in testinit.go`s init3.3:%d\n", 0)
}
func init() {
fmt.Printf("init WhatIsThe in testinit.go`s init3.4:%d\n", 1)
}
func main() {
p1.DoNothing()
}
运行结果:
$ go run testinit.go
p1 package, x:1.200000
init package level variable, WhatIsThe: 2.400000
init package level variable, WhatIsThe: 2.500000
init package level variable, WhatIsThe: 2.600000
init WhatIsThe in testinit.go`s init3.3:0
init WhatIsThe in testinit.go`s init3.4:1
do nothing.
总结
在一个go文件中,初始化规则: 1.引入的包 2. 当前包中的常量变量 3. 当前包中的init
4.main
函数
如图:
注意:
0: 当前Go源文件中, 每个被import
的包,按其在源文件中出现的顺序初始化.
1:如果当前包有多个init
在不同的源文件中, 则按源文件名以字典从小到大的顺序,小的先被执行到, 同一包且同一源文件中的init
,则按照
其出现在文件中的先后顺序依次初始化;当前包的package level变量常量也遵循这个顺序;其实准确来说,应是按提交给编译器的源文件顺序为准
只是在提交编译器之前,go命令行工具对源文件名按照字典顺序排序了.
2:init
只可以由go runtime
自己的调用,我们在代码中不可以显示调用,也不可以被引用,如: 赋值给a function variable
3: 包A
引入包B
,包B
又引入包C
, 则包的初始化顺序为: C-->B--A
4: 引入包必须避免死循环, 如A
引B
, B
引C
, C
引A
5: 一个包被其他多个包引入,如 A-->B-->C
和H--I--C
, C
被其他包引了2次,但是注意包C
只是被初始化一次.
6:另一个大原则,被依赖的总是先被初始化
7:main
包总是被最后一个初始化, 这个很好理解.
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付