协程中参数直接使用,和传参的区别是什么,为什么会造成这种结果

本文阅读 2 分钟
首页 golang 正文
题目来源:字节跳动

作者:ORVR

协程中参数直接使用,和传参的区别是什么,为什么会造成这种结果

以一个例子说明

直接使用

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(ctx,func(ctx context.Context) {
            fmt.Println(i)
            wg.Done()
        })

    }
    wg.Wait()
}

执行输出结果

10 10 10 10 10 10 10 10 10 10

传参使用

func main() {

    wg := sync.WaitGroup{}

    for i := 0; i < 10; i++ {

    wg.Add(1)

    go func(ctx,func(ctx context.Context) {

        fmt.Println(i)

        wg.Done()

        })(i)

    }

   wg.Wait()
}

执行输出结果

0 9 3 4 5 6 7 8 1 2

产生这种结果的原因是,对于一部协程来说,函数在执行异步执行注册时,该函数并未真正开始执行注册时只在goroutine的栈中保存了变量i的内存地址,而一旦开始执行函数时才会去读取变量i的值,而这时变量i的值已经自增到了10,改进的方案就是在注册异步执行函数的时候,把变量的值也一并传递获取,或者吧当前变量i的值赋值给一个不会改变的临时变量中,在函数中使用该临时变量而不是直接使用i

本文来自投稿,不代表本站立场,如若转载,请注明出处:
了解中间件吗?有什么好处?
« 上一篇 09-17
Go 高并发的特点
下一篇 » 09-17

发表评论

发表评论