go语言循环变量
阅读go语言圣经第五章第六节介绍到了捕获迭代变量
package main import ( "fmt" ) func main() { var lis []func() for i := 0; i < 10; i++ { lis = append(lis, func() { fmt.Println(i) }) } for _, f := range lis { f() } }
这段代码执行结果是打印了10个10
出现这个结果的原因是for循环的循环体会共享循环变量i的值,因此第二个for循环开始调用f函数时,他们的i共享的是最后一次的循环变量i的值,此时i已经变成了10。
如何确保函数打印循环到某一时刻的i值呢?
package main import ( "fmt" ) func main() { var lis []func() for i := 0; i < 10; i++ { i := i lis = append(lis, func() { fmt.Println(i) }) } for _, f := range lis { f() } }
以上代码实现该效果。我的理解是:i:=0;i<10;i++是一个词法块,它是for循环体的上一级作用域,原来的for循环体找i是从上级作用域找到的。所以,只要我们能让for循环体找i时从自己的作用域找就可以了,因此,我们需要在循环体内重新声明一个变量保存上级作用域中的i在当前循环的值。这里我声明的变量还是i(go语言圣经也用原变量名,应该是让读者记忆更深刻吧)