Golang闭包不存储捕获的变量?

Bob*_*Bob 3 closures function return-value go

在下面这段代码中,我希望输出为0,1,2,3,...,9.但是,只产生输出10,10,...,10.

package main

import "fmt"

func adder() []func() {
    out := []func(){}
    for i := 0; i < 10; i++ {
        out = append(out, func() { fmt.Println(i) })
    }

    return out
}

func main() {
    out := adder()
    for i := 0; i < 10; i++ {
        out[i]()
    }
}
Run Code Online (Sandbox Code Playgroud)

我的心理模型表明,每次在for循环中都会生成并存储一个新函数,但似乎并非如此.有没有一个解决方案来生成新的功能而不修改签名(没有参数或全局变量),但仍保持i的当前值?

Adr*_*ian 5

每次迭代都会创建一个新函数,但它们都会关闭同一个变量i.该变量在每次迭代时都会更新,直到最后一次,因此当您执行并执行所有这些函数时,它们都引用i相同的值,具有相同的值10.

如果您不想要这种行为,则不得关闭循环变量:

for i := 0; i < 10; i++ {
    temp := i
    out = append(out, func() { fmt.Println(temp) })
}
Run Code Online (Sandbox Code Playgroud)

  • @Bob 是的,这是同样的想法,但由于你的问题与 goroutine 无关,我不想混淆这个问题。它绝对是最常见的,因为它与 goroutine 相关。 (2认同)