Go语言的初始化顺序,包,变量,init详解
在Go语言中,程序的初始化是从包的引入开始的。初始化的顺序非常重要。
包的初始化顺序
在包被import引入到程序中时,Go将按照以下顺序初始化包:
1.首先,Go将计算所有包级别的变量的值并执行所有init函数。这假定这些变量和init函数没有依赖于任何其他包。它们只依赖于标准库和编译器定义的本地实体。
2.接着,Go将按照以下顺序对每个非main包执行其依赖关系图上的init函数。
对一个包的初始化仅在第一次加载时运行。可以通过导入路径来引用这个包,也可以通过空白标识符(_)来强制编译器加载这个包。即使是没有用到的包,编译器也会加载它们,并触发它们的init函数。
注意:如果循环导入了两个或多个包,Go编译器将会报错。
示例1:包的初始化顺序
假设有以下三个包:pkgA,pkgB,pkgC。它们依赖关系如下:
main -> pkgA -> pkgB -> pkgC
现在,让我们假设main包导入pkgA包,pkgA包导入pkgB包,pkgB包导入pkgC并且三个包中均有一个init函数。在这个情况下,初始化顺序如下:
1.pkgC被导入,并且pkgC的init函数被执行。
2.pkgB被导入,并且pkgB的init函数被执行。
3.pkgA被导入,并且pkgA的init函数被执行。
需要注意的是,即使只导入了pkgA包,系统会自动将pkgB和pkgC包加载到内存,并执行它们的init函数。这是因为pkgA依赖pkgB,而pkgB依赖pkgC。
变量的初始化顺序
在每个包中,变量的初始化值是通过声明它们时提供的表达式来确定的。在一个大的编译单元中,包的变量将采用以下顺序进行初始化:
1.包级别变量,不依赖其他包里面的元素。
2.按包的依赖性顺序初始化每个包级别变量。
示例2:变量的初始化顺序
package main
import "fmt"
var a = "hello"
func init() {
fmt.Println("init1")
}
func init() {
fmt.Println("init2")
}
func main() {
fmt.Println(a)
}
上面的代码中,变量a
被初始化为字符串"hello"。在这个示例中,init1
和init2
在a
被初始化之前执行。
init函数的使用
每个包可以包含任意数量的init函数。这些函数是在程序运行开始时按顺序执行的。
init函数不能接受任何参数或返回值。也就是说,它们在运行时无法与其他函数进行通信。
示例3:init函数的使用
package main
import "fmt"
func init() {
fmt.Println("init1")
}
func init() {
fmt.Println("init2")
}
func main() {
fmt.Println("main")
}
上面的代码中,程序运行时将输出以下内容:
init1
init2
main
需要注意的是,init函数可以用来执行任何有关包的操作。这可能包括一些包的初始化逻辑、变量初始化或HTTP路由注册等等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:go语言的初始化顺序,包,变量,init详解 - Python技术站