
在Go语言中,init()函数内若用:=而非=为包级变量赋值,会意外创建同名局部变量,导致包级变量保持零值(如nil),这是初学者常见的作用域陷阱。
在go语言中,`init()`函数内若用`:=`而非`=`为包级变量赋值,会意外创建同名局部变量,导致包级变量保持零值(如`nil`),这是初学者常见的作用域陷阱。
Go语言的init()函数用于包初始化,会在main()执行前自动调用,且仅执行一次。但其内部变量作用域规则与普通函数完全一致:使用:=是短变量声明(short variable declaration),它总是在当前作用域定义新变量;而=才是赋值操作(assignment),作用于已声明的变量。
在你的pkg2包中:
package pkg2
var MyVariable string // ✅ 正确:声明为包级变量(需指定类型)
func init() {
MyVariable := "something" // ❌ 错误:`:=' 创建了新的局部变量MyVariable
// 此时包级MyVariable未被修改,仍为零值("" 或 nil,取决于类型)
}上述代码中,MyVariable := "something" 实际等价于:
var MyVariable string = "something" // 局部变量,作用域仅限于init函数内
因此,init()结束后该局部变量即被销毁,包级MyVariable从未被赋值,自然保持其零值(若为指针/接口/切片等则为nil)。
立即学习“go语言免费学习笔记(深入)”;
✅ 正确写法如下:
package pkg2
var MyVariable string // 显式声明类型(不可省略)
func init() {
MyVariable = "something" // ✅ 使用 = 赋值给已声明的包级变量
}⚠️ 注意事项:
- 包级变量声明必须指定类型(如
string、*http.Client等),不能使用var MyVariable(缺少类型)或var MyVariable = "xxx"(编译错误:无法在包级使用短声明); -
init()中不可使用:=初始化包级变量——这是语法限制,也是设计意图:强制开发者明确区分“声明”与“赋值”; - 若变量需在
init()中动态初始化(如读取环境变量、连接数据库),务必确保使用=并提前完成声明。
? 小技巧:启用go vet或IDE静态检查可捕获此类问题(例如提示“assignment to MyVariable in init shadows declaration at …”)。
总结:init()不是魔法——它遵循Go全部作用域和声明规则。牢记 := = 声明 + 赋值,= = 仅赋值,即可避免绝大多数初始化失效问题。


















