1 在循环迭代器变量上使用goroutines
错误的写法:
1
2
3
4
5
for _, val := range values {
go func() {
fmt.Println(val)
}()
}
上面的for循环可能无法达到您的预期,因为它们的val变量实际上是一个单独的变量,它接受每个slice元素的值。 因为闭包只绑定到那个变量,所以很有可能当你运行这个代码时,你会看到每次迭代打印的最后一个元素而不是序列中的每个值,因为goroutines可能不会开始执行,直到 循环之后。
编写闭包循环正确的写法应该是:
1
2
3
4
5
for _, val := range values {
go func(val interface{}) {
fmt.Println(val)
}(val)
}
通过将val作为参数添加到闭包中,在每次迭代时计算val并将其放置在goroutine的堆栈上,因此每个切片元素在最终执行时都可用于goroutine。
Note that without executing this closure as a goroutine, the code runs as expected. The following example prints out the integers between 1 and 10.
1
2
3
4
5
for i := 1; i <= 10; i++ {
func() {
fmt.Println(i)
}()
}
即使闭包仍然对同一个变量关闭(在这种情况下,是i),它们也是在变量改变之前执行的,导致了期望的行为。 点击查看