循环执行func闭包

基里尔

当执行以下代码时,我会得到第一个循环完成时的期望值(从0到9的顺序)。但是,当第二个循环结束时,结果却不是我期望的(我期望的结果与第一个循环相同,但它只显示“ 10”):

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)

        go func(j int) {
            defer wg.Done()

            fmt.Println(j)
        }(i)
    }

    wg.Wait()

    fmt.Println("done first")

    for i := 0; i < 10; i++ {
        wg.Add(1)

        go func() {
            defer wg.Done()

            fmt.Println(i)
        }()
    }

    wg.Wait()

    fmt.Println("done second")
}

输出:

0
1
2
3
4
5
6
7
8
9
done first
10
10
10
10
10
10
10
10
10
10
done second

为什么第二个循环不打印序列?

西蒙·怀特黑德

因为第一个每次都会获得循环计数器的副本。而第二个则将变量捕获为闭包的一部分。

首先,在循环的每次迭代中将其传递给这里

go func(j int) {
    defer wg.Done()

    fmt.Println(j)
}(i) // <------------ its passed in here as part of each loop iteration

第二个计数器什么也不接收..因此,循环计数器i被捕获为闭包的一部分。到第一次执行例程执行时,for循环已完成。循环完成将i变量(现在是闭包的一部分)设置为10。执行例行程序#1并打印i..的值,该值现在已经是10,其余的都照做。

TLDR:这里的问题是循环在计划任何go例程运行之前就已经完成了-循环是如此之快。因此,i == 10当go例程运行时。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Javascript闭包-在for循环中传递infowindow id

来自分类Dev

循环和闭包中的Println输出不同的值

来自分类Dev

双闭包如何破坏循环引用?

来自分类Dev

如何在循环内的闭包中保留参数?

来自分类Dev

这种模式是否在闭包中引起循环引用?

来自分类Dev

闭包函数从循环中追加所有索引

来自分类Dev

使js闭包立即执行

来自分类Dev

在循环中修复闭包

来自分类Dev

Swift进行单元测试:闭包主体未执行

来自分类Dev

添加事件在循环中无法正常使用闭包

来自分类Dev

for和foreach循环中的闭包行为不同

来自分类Dev

使用循环和闭包设置元素的innerHTML

来自分类Dev

scala:在闭包中强制执行不可变类型

来自分类Dev

在for-in循环中使用尾随闭包

来自分类Dev

如何以参数为参数传递闭包并执行它?

来自分类Dev

闭包后执行财产

来自分类Dev

Swift func提供当前的CLLocation(使用闭包NOT委托)

来自分类Dev

执行,闭包和作用域

来自分类Dev

双闭包如何破坏循环引用?

来自分类Dev

循环,闭包和Javascript中的addEventListener

来自分类Dev

Swift进行单元测试:闭包主体未执行

来自分类Dev

scala:在闭包中强制执行不可变类型

来自分类Dev

JavaScript闭包和for循环

来自分类Dev

未执行 Swift 转义闭包

来自分类Dev

Swift:完成闭包永远不会执行?

来自分类Dev

具有传递 Observable 的闭包的通用 func

来自分类Dev

在闭包 Swift 中保留循环

来自分类Dev

Python 中的闭包何时完成执行或超出范围?

来自分类Dev

JavaScript 执行上下文和闭包