Go语言的初始化顺序,包,变量,init

Posted by     "" on Monday, December 16, 2019

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函数 如图: Go初始化顺序 注意:
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: 引入包必须避免死循环, 如AB, BC, CA
5: 一个包被其他多个包引入,如 A-->B-->CH--I--C, C被其他包引了2次,但是注意包C只是被初始化一次.
6:另一个大原则,被依赖的总是先被初始化
7:main包总是被最后一个初始化, 这个很好理解.

「真诚赞赏,手留余香」

Richie Time

真诚赞赏,手留余香

使用微信扫描二维码完成支付