我是Go的新手。运行多个go文件(包括程序包,变量和init
函数)时,我陷入了初始化顺序。
据我所知,有几个规则:
导入的软件包和init
函数应根据其出现顺序进行调用。
如果文件A导入文件B而文件B导入文件C,则初始化顺序为C-> B-> A。
依赖关系总是首先执行。
包main
总是最后执行。
有一个我很困惑的例子(有人告诉我初始化顺序是从小数字到大数字,例如1.1在1.2之前执行,1.2在2.1之前执行,等等)
// p1.go
package p1
import "fmt" //1.1
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 "p1" //1
import "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() { //3.4
fmt.Printf("init WhatIsThe in testinit.go`s init3.4: %d\n", 1)
}
func main() { //4
p1.Donothing() //5
}
///////////////////////////////////////////////// ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ////
// z.go
package main
import "fmt"
var WhatIsThe7 = AnswerToLife(2.7) //2.7
var WhatIsThe8 = AnswerToLife(2.8) //2.8
var WhatIsThe9 = AnswerToLife(2.9) //2.9
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)
}
我对那些事情感到困惑:
当文件声明软件包main
时,可以缺少main
函数吗?
如果有多个软件包main
,它们之间的关系是什么?
据我从Python,Javascript等其他语言了解,应该有一个“主文件”。 Go语言怎么样?
所有软件包main
(s)的初始化顺序是什么?
我对序列2.1〜2.9感到困惑,为什么要顺序执行它们而不是执行文件init
,a.go
和testinit.go
中的z.go
函数?
答案 0 :(得分:0)
通过将单个未导入的程序包(称为主程序包)与它所导入的所有程序包可传递地链接起来,可以创建一个完整的程序。主程序包必须具有程序包名称
main
,并声明一个不带参数也不返回值的函数main
。func main() { … }
通过初始化主程序包然后调用函数main开始程序执行。当该函数调用返回时,程序退出。它不等待其他(非主)goroutine完成。
请注意,主软件包与名称为main
的软件包之间存在区别。
如果软件包文件包含主软件包,则该软件包必须具有main
功能。否则,名为main
的程序包中的文件不需要具有main
函数。
程序的执行从上面定义的主程序包开始。其他名为main
的软件包没有特殊状态。
可以有多个main
软件包。只有一个软件包可以满足主软件包的要求。
程序包的初始化顺序取决于程序包之间的导入关系。任何程序包的名称在确定初始化顺序中都不起作用。