封闭变量在循环中被覆盖

封闭变量在循环中被覆盖

问题描述:

I am trying to build an array of functions that contain an enclosed variable (in this case a string) but I was getting some unexpected output. I figure the reason I am getting this output is because the func literal being appended is actually a pointer to code that is being changed after each iteration.

Is there a way to new() or make() a function type so that append() will get a different function instance per iteration instead?

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()
    }
}

Outputs:

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

我正在尝试构建包含封闭变量(在这种情况下为字符串)的函数数组,但是 得到一些意外的输出。 我知道得到此输出的原因是因为附加的func文字实际上是指向每次迭代后都会更改的代码的指针。 p>

是否有一种方法可以 new () code>或 make() code>一种函数类型,以便 append() code>每次迭代都会获得不同的函数实例? p>

 包main 
 
导入“ log” 
 
var函数[] func()
 
func main(){
表示_,s:=范围[...]字符串{“ 再见”,“残酷”,“世界”} {
函数= append(函数,func(){
 log.Println(s)
})
} 
表示_,f:=范围函数{  
f()
} 
} 
  code>  pre> 
 
 

输出: p>

  2014/11/23 18:  13:16世界
2014 / 11/23 18:13:16世界
2014 / 11/23 18:13:16世界
  code>  pre> 
  div>

Each iteration of the loop uses the same instance of the variable s, so each closure shares that single variable. To bind the current value of s to each closure as it is launched, one must modify the inner loop to create a new variable each iteration. For example,

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()
    }
}

Output:

2009/11/10 23:00:00 goodbye
2009/11/10 23:00:00 cruel
2009/11/10 23:00:00 world

References:

What happens with closures running as goroutines?

Captured Closure (for Loop Variable) in Go