在使用golang时常见的错误

 

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),它们也是在变量改变之前执行的,导致了期望的行为。 点击查看

闭包作为goroutines运行会发生什么

– 返回顶部 –