
init() 是 Go 语言中特殊的预定义函数,由运行时自动调用,用于包初始化;它不能被显式调用、无参数、无返回值,且每个源文件可定义多个。试图在 main() 中调用 init() 会导致编译错误。
`init()` 是 go 语言中特殊的预定义函数,由运行时自动调用,用于包初始化;它不能被显式调用、无参数、无返回值,且每个源文件可定义多个。试图在 `main()` 中调用 `init()` 会导致编译错误。
在 Go 中,init() 函数具有严格的语义和执行时机约束:它不是普通函数,而是由 Go 运行时在包加载阶段自动、隐式、仅执行一次的初始化钩子。其设计目标是解耦初始化逻辑与主程序流程,确保变量初始化、标志注册、全局状态设置等操作在 main() 执行前完成。
例如,你定义的代码:
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}✅ 正确行为:当该文件所属包被导入(或作为 main 包启动)时,init() 会自动执行,成功注册命令行标志 "flagname"。你无需且不可在 main() 中写 init() —— 这会触发编译错误 undefined: init,因为 init 不是用户可调用的标识符,而是一个保留关键字级别的特殊函数。
⚠️ 注意事项:
立即学习“go语言免费学习笔记(深入)”;
- init() 必须是无参数、无返回值的函数(func init()),否则编译失败;
- 同一文件中可定义多个 init() 函数,它们按声明顺序依次执行;
- 所有 init() 函数在包内所有包级变量初始化完成后执行,且在所有依赖包的 init() 全部执行完毕之后;
- init() 不能被反射调用,也不能出现在接口、方法集或作为值传递。
✅ 正确的 main.go 示例:
package main
import (
"flag"
"fmt"
)
var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
func main() {
flag.Parse() // 解析命令行参数(必须在 init 之后、main 中显式调用)
fmt.Printf("flagname = %d\n", flagvar)
}运行效果:
go run main.go -flagname 5678 # 输出:flagname = 5678
? 总结:Go 的 init() 是编译器管理的“自动初始化器”,不是常规函数。若需复用初始化逻辑,请将其提取为普通函数(如 setupFlags()),再在 init() 或 main() 中显式调用——这才是符合 Go 语言惯用法的清晰、可控、可测试的设计方式。


















