Go 语言中的 init() 是由运行时自动调用的特殊函数,用于包级初始化;它不能也不应被显式调用,否则会编译报错或引发未定义行为。
go 语言中的 `init()` 是由运行时自动调用的特殊函数,用于包级初始化;它不能也不应被显式调用,否则会编译报错或引发未定义行为。
在 Go 中,init() 函数具有严格的语义和执行时机约束:它不是普通函数,而是由 Go 运行时在包加载阶段自动、隐式、仅执行一次的初始化钩子。你无法在 main() 或任何其他函数中通过 init() 语法调用它——这会导致编译错误(如 undefined: init),因为 init 不是一个可导出的标识符,也不属于用户可调用的函数命名空间。
例如,以下代码是错误且非法的:
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
func main() {
init() // ❌ 编译失败:undefined: init
}✅ 正确做法是:完全移除手动调用,让 Go 自动触发 init。只要该函数存在于包中(通常在 main 包或依赖包内),它就会在 main() 执行前、所有包变量初始化完成后自动运行。上述 flag 注册逻辑将如期生效:
package main
import "flag"
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
func main() {
flag.Parse() // 必须调用 Parse() 才能解析命令行参数
println("flagname =", flagvar)
}? 关键注意事项:
- 一个源文件可定义多个 init() 函数,它们按声明顺序依次执行;
- 同一包内不同文件的 init() 按文件名(字典序)执行,但不建议依赖此顺序;
- init() 无参数、无返回值(niladic),不可被导出或引用;
- 若需复用初始化逻辑,应将其封装为普通函数(如 setupFlags()),再在 init() 或 main() 中调用。
? 总结:init() 是 Go 的“自动启动器”,不是 API 接口。理解其自动性与生命周期,是写出健壮、符合 Go 惯例代码的基础。

















