go闭包

for j := 0; j < 3; j++ {
// 错误:闭包引用共享的 j
go func() {
fmt.Println(j)
}()
}
time.Sleep(100ms) // 等协程执行完

预期输出:0、1、2实际输出:大概率是 3、3、3(因为循环结束后 j=3,协程才执行)。

三、传 j 的副本((j))为什么能解决问题?
代码中 go func(idx int) { ... }(j) 的关键是:
匿名函数定义了参数 idx int;
启动协程时,立刻将当前循环的 j 值作为实参传给 idx(相当于 “快照”);
idx 是每个协程独立的局部变量,不再依赖外部的循环变量 j。

for j := 0; j < 3; j++ {
// 正确:将 j 的当前值传给 idx(副本)
go func(idx int) {
fmt.Println(idx)
}(j)
}
time.Sleep(100ms)

实际输出:0、1、2(顺序可能乱,但值正确)。

posted @ 2025-12-17 11:47  kevinWwm  阅读(1)  评论(0)    收藏  举报