You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言闭包嵌套问题:为何输出全为3?与单层闭包的差异

Go语言闭包与循环变量的陷阱解析

第一个代码输出3 3 3的原因

Go语言里,for range循环的迭代变量(这里的uid)是同一个变量,全程复用同一块内存空间。每次循环只是更新这个变量的值,并不会创建新的变量。

看这段代码的结构:外层是匿名goroutine,内部嵌套了一个接收id参数的函数并传入uid。问题在于goroutine的调度是异步的,当这些goroutine真正开始执行内部函数时,外层的for循环大概率已经完成了所有迭代,此时uid的值已经被更新为切片的最后一个元素3。所以三个goroutine最终传入内部函数的都是3,输出自然全是3。

与第二个代码的差异

第二个代码把uid直接作为参数传给goroutine的匿名函数:

go func(id int) {
    defer wg.Done()
    fmt.Println(id)
}(uid)

Go函数的参数传递是值传递,每次循环迭代时,都会把当前uid的当前值拷贝一份,作为参数id传入函数。这意味着每个goroutine拿到的都是迭代瞬间uid的副本,分别是1、2、3。

但由于goroutine的执行顺序由Go调度器决定,没有固定顺序,所以输出会是1、2、3的随机排列(比如示例中的3 1 2),但不会出现全是3的情况。

内容的提问来源于stack exchange,提问作者sheeks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:10:10