2014-11-24 112 views
3

我想构建一个包含封闭变量(在这里是一个字符串)的函数数组,但我得到了一些意外的输出。我想我得到这个输出的原因是因为被附加的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 

回答

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

+0

有趣。所以它实际上是迭代器本身的范围而不是函数? – BlinkyTop 2014-11-24 02:30:24