封闭变量在循环中被重写

时间:2014-11-24 02:22:19

标签: pointers go

我正在尝试构建一个包含封闭变量的函数数组(在本例中为一个字符串),但是我得到了一些意想不到的输出。我认为我得到此输出的原因是因为附加的func文字实际上是指向每次迭代后更改的代码的指针。

有没有办法new()make()函数类型,以便append()每次迭代会获得不同的函数实例?

package main

import "log"

var functions []func()

func main() {
    for _, s := range [...]string{"goodbye", "cruel", "world"} {
        functions = append(functions, func() {
            log.Println(s)
        })
    }
    for _, f := range functions {
        f()
    }
}

输出:

2014/11/23 18:13:16 world
2014/11/23 18:13:16 world
2014/11/23 18:13:16 world

1 个答案:

答案 0 :(得分:3)

循环的每次迭代都使用变量s的相同实例,因此每个闭包共享该单个变量。要在启动时将s的当前值绑定到每个闭包,必须修改内部循环以在每次迭代时创建一个新变量。例如,

package main

import "log"

var functions []func()

func main() {
    for _, s := range [...]string{"goodbye", "cruel", "world"} {
        s := s // create new s
        functions = append(functions, func() {
            log.Println(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

参考文献:

What happens with closures running as goroutines?

Captured Closure (for Loop Variable) in Go