编程笔记 Golang基础 039 init 函数
一、init
函数的关键特性与用法
-
定义和调用:
init
函数没有参数也不返回任何值。init
函数不需要显式声明其返回类型,直接使用func init() { ... }
即可定义。init
函数不能被其他函数调用,它们由 Go 运行时自动、隐式地调用。
-
执行时机:
- 当一个包(package)被导入时,该包中的所有
init
函数按照源代码中出现的顺序依次执行。 - 如果一个包导入了其他的包,则先执行所导入包中的所有
init
函数(递归执行),再执行当前包的init
函数。 - 在执行所有的
init
函数之后,才会执行main
包中的main
函数。
- 当一个包(package)被导入时,该包中的所有
-
数量限制:
- 在同一个包中可以有任意多个
init
函数,Go 会确保它们按照源码编写的顺序执行。
- 在同一个包中可以有任意多个
-
用途:
- 初始化全局变量或静态资源。
- 执行依赖检查或者配置验证等一次性准备工作。
- 注册包级服务或组件到全局系统中。
- 设置默认值或计算复杂的初始化表达式结果。
-
注意事项:
- 由于
init
函数的执行顺序不可控(取决于包导入的顺序和文件内定义的顺序),因此应尽量避免不同init
函数间的逻辑依赖。 - 不同包中的
init
函数之间不能互相调用。 init
函数内部发生的错误无法捕获和处理,如果需要错误处理机制,通常会在init
中触发 panic,并通过外部机制如日志记录或全局恢复来管理。
- 由于
二、应用示例
// 包 mypkg 的两个 init 函数
package mypkg
var globalVar int
func init() {
// 初始化 globalVar 变量
globalVar = calculateInitialValue()
}
func init() {
// 检查 globalVar 是否有效
if globalVar < 0 {
log.Fatal("Invalid initial value for globalVar")
}
}
小结
总之,在 Go 语言中,init
函数是实现包级别初始化逻辑的一种简洁手段,它简化了程序员在程序启动阶段设置初始状态的工作,同时保持了代码的整洁性和组织性。然而,由于其隐式调用和固定执行顺序的特点,开发者在使用时需谨慎考虑其影响。