Go: init()执行顺序问题

本文详细介绍了Go语言中init()函数的执行时机及其在程序启动过程中的作用。解释了init()函数与main()函数的执行顺序,以及如何通过init()函数实现包级别的初始化逻辑。

init()函数会在包被初始化后自动执行,并且在main()函数之前执行,但是需要注意的是init()以及main()函数都是无法被显式调用的。

那么init()是不是最先执行的呢?

答案是否定的,首先,在他之前会进行全局变量的初始化。

当我们导入其他包时,会先初始化导入的包,

而初始化包时,会先加载全局变量,而后从上到下加载init()函数,

当被导入的包的init()函数执行完毕后,执行调用方的全局变量加载,init()函数的顺序加载,之后执行main()函数。

### init() 函数的特性 Go语言中的 `init()` 函数是一种特殊的函数,主要用于完成程序初始化工作。其特性包括: - `init()` 函数是可选的,可以没有。 - 与 `main()` 函数一样,`init()` 函数不能有入参和返回值。 - 与 `main()` 函数一样,`init()` 函数会自动执行,不能被其他函数调用。 - 一个包内可以有多个 `init()` 函数,即可以在包的多个源文件中定义多个 `init()` 函数。一般建议在与包同名源文件中写一个 `init()` 函数,这样可读性好且便于维护[^2]。 - 一个源文件可以有多个 `init()` 函数[^4]。 ### init() 函数执行顺序 Go语言中 `init()` 函数执行顺序遵循一定的规则: - 每个包中的 `init()` 函数会在该包的所有全局变量初始化完成后执行。 - 如果一个包被多个其他包依赖,那么该包的 `init()` 函数会在所有依赖它的包的 `init()` 函数之前执行。 - 对于同一个包内的多个 `init()` 函数,它们之间的执行顺序是不确定的。因此,在编写代码不应依赖于这些 `init()` 函数的具体执行顺序[^4]。 - 在程序启动,`init()` 函数会在 `main()` 函数之前被调用。这意味着 `init()` 函数执行流程是在 `main()` 函数之前的[^3]。 下面是一个简单的示例来展示 `init()` 函数的使用: ```go package main import ( "fmt" ) // init 函数会在 main 函数执行前被调用 func init() { fmt.Println("init...") } func main() { fmt.Println("main...") } ``` 在这个例子中,当程序运行,首会打印出 "init...",然后才会打印出 "main..."。 ### 示例:多个 init() 函数 对于同一个包内的多个 `init()` 函数,虽然它们的执行顺序是不确定的,但是我们可以看到它们都在 `main()` 函数之前被执行了。 ```go package sub import "fmt" // init 函数没有参数,没有返回值,原型固定如下 // 一个包中包含多个 init ,调用顺序是不确定的 func init() { fmt.Println("这个是 package sub 中的第一个 init()") } func init() { fmt.Println("这个是 package sub 中的第二个 init()") } func Sub(a, b int) int { return a - b } ``` 在这个例子中,当 `sub` 包被导入,两个 `init()` 函数都会被调用,但它们的具体执行顺序是不确定的[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值