初始化顺序没有特别之处,就是文件内const->var->init func->main func,先进入按书面顺序进入import。特别需要注意的我看只有init不会调用两次。
很多博客都提到了下面一点
一个init函数里可能会启动其它goroutine,即在初始化的同时启动新的goroutine。然而,初始化依旧是顺序的,即只有上一个init执行完毕,下一个才会开始( An init function may launch other goroutines, which can run concurrently with the initialization code. However, initialization always sequences the init functions: it will not invoke the next one until the previous one has returned.)
但我试了并不如此。如此看来golang的init依然很简单,没有太多的隐式规则,这很符合其语言设计本身的初衷。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package a
import "fmt"
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)
}
func AFunc() {
fmt.Println("AFunc")
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package p1
import "fmt" //1.1
import _ "coding/demo/init/a"
var x float32 = 1.2 //1.2
func init() { //1.3
go func() {
fmt.Println("gorutine 1.3")
}()
fmt.Printf("p1 package, x:%f\n", x) //1.4
}
func Donothing() {
fmt.Println("do nothing")
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package z
import "fmt"
func init() { //3.5
fmt.Printf("init WhatIsThe in z.go`s init 3.5: %d\n", 4)
}
func init() { //3.6
fmt.Printf("init WhatIsThe in z.go`s init 3.6: %d\n", 5)
}
func Zfunc() {
fmt.Println("Zfunc")
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package main
import (
_ "coding/demo/init/a"
"coding/demo/init/p1"
_ "coding/demo/init/z"
"fmt"
)
func AnswerToLife(index float32) float32 {
fmt.Printf("init package level variable, WhatIsThe: %f\n", index)
return index
}
func init() { //3.3
go func() {
fmt.Println("gorutine 3.3")
}()
fmt.Printf("init WhatIsThe in testinit.go`s init3.3: %d\n", 0)
}
func init() { //3.4
go func() {
WhatIsThe4 = 7.9
fmt.Println("gorutine 3.4")
}()
fmt.Printf("init WhatIsThe in testinit.go`s init3.4: %d\n", 1)
}
var WhatIsThe4 = AnswerToLife(yu) //2.4
var WhatIsThe5 = AnswerToLife(b) //2.5
var WhatIsThe6 = AnswerToLife(2.6) //2.6
var b float32 = 9.7
var yu float32 = 9.8
func main() { //4
fmt.Println(WhatIsThe4)
p1.Donothing() //5
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
init WhatIsThe in a.go `s init 3.1: 2
init WhatIsThe in a.go`s init 3.2: 3
p1 package, x:1.200000
init WhatIsThe in z.go`s init 3.5: 4
init WhatIsThe in z.go`s init 3.6: 5
init package level variable, WhatIsThe: 9.800000
init package level variable, WhatIsThe: 9.700000
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
9.8
do nothing
|
参考
https://golang.org/ref/spec#Package_initialization
https://medium.com/golangspec/init-functions-in-go-eac191b3860a
https://maiyang.me/post/2019-01-03-init-order-in-golang/