初始化顺序没有特别之处,就是文件内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/