

新闻资讯
技术学院在 go 中,for 循环中创建的闭包若直接引用循环变量,会导致所有闭包共享同一变量实例,从而输出意外的重复值;正确做法是在每次迭代中通过短变量声明(s := s)显式创建新变量副本。
这是 Go 开发中一个高频且易被忽视的经典陷阱:循环变量在闭包中被意外复用。根本原因在于:Go 的 for 循环体复用同一个变量内存地址——每次迭代仅更新其值,而非创建新变量。因此,所有匿名函数捕获的都是对同一个 s 变量的引用,当循环结束时,s 的最终值(即 "world")成为所有闭包实际读取的内容。
✅ 正确解法:在循环体内使用 短变量声明 创建独立副本:
package main
import "log"
var functions []func()
func main() {
for _, s := range [...]string{"goodbye", "cruel", "world"} {
s := s // ✅ 关键:为本次迭代创建新的局部变量 s
functions = append(functions, func() {
log.Println(s) // 此处 s 绑定的是本轮迭代的独立副本
})
}
for _, f := range functions {
f()
}
}? 输出结果将符合预期:
2009/11/10 23:00:00 goodbye 2009/11/10 23:00:00 cruel 2009/11/10 23:00:00 world
⚠️ 注意事项:
? 总结:闭包捕获的是变量的绑定(binding),而非值的快照;要捕获当前值,必须捕获一个生命周期独立、值不变的新变量。养成在循环中创建闭包前主动“复制”循环变量的习惯,是写出健壮 Go 代码的重要实践。