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

时间:2018-11-15 17:57:49

标签: function go closures return-value

在下面的这段代码中,我希望输出为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]()
    }
}

我的思维模型建议每次都在for循环中生成并存储一个新函数,但事实并非如此。是否有解决方案,可以在不修改签名(无参数或全局变量)但仍保持i的当前值的情况下生成新函数?

1 个答案:

答案 0 :(得分:5)

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

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

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