Go 并发:探索 for 循环中匿名函数的令人惊讶的行为
在这次探索中,我们将揭示一个意想不到的情况使用 for 循环和匿名时 Go 并发表现出的行为
问题:
想象一下运行以下代码片段以使用sync.WaitGroup测试并发性:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func() { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }() } wg.Wait() }
令人惊讶的是,观察到的输出是:6,6,6,6,6,而不是预期的序列:1, 2, 3, 4, 5.
解释:
要理解此行为,我们参考 Go 常见问题解答“闭包作为 goroutine 运行会发生什么?” 。在这种情况下,直到 for 循环完成后才调度 goroutine。因此,此时 i 已前进到 6。当 goroutine 执行时,它们都打印了 i 的捕获值,即 6。
将 i 作为参数传递给匿名函数,有效地创建了当前值,捕获调用时的值。这解释了在代码的修改版本中观察到的预期行为。
以上是为什么我的 Go 并发代码打印 6 六次而不是 1 到 5?的详细内容。更多信息请关注PHP中文网其他相关文章!