微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么Golang在goroutines中对闭包的处理方式不同?

如何解决为什么Golang在goroutines中对闭包的处理方式不同?

Go中的闭包在词法范围内。这意味着闭包内从“外部”范围引用的任何变量都不是副本,而是实际上是引用。一for环竟重复使用相同的变量多次,所以你介绍的读/写之间的竞争条件s变量。

但是x正在分配一个新变量(带有:=)并进行复制s,这导致每次都是正确的结果。

通常,最佳做法是传递所需的任何参数,以使您没有引用。例:

for _, s := range []string{"foo", "bar"} {
    x := s
    go func(s string) {
        fmt.Printf("s: %s\n", s)
        fmt.Printf("x: %s\n", x)
    }(s)
}

解决方法

考虑以下Golang代码(也在Go Playground上):

package main

import "fmt"
import "time"

func main() {
    for _,s := range []string{"foo","bar"} {
        x := s
        func() {
            fmt.Printf("s: %s\n",s)
            fmt.Printf("x: %s\n",x)
        }()
    }
    fmt.Println()
    for _,"bar"} {
        x := s
        go func() {
            fmt.Printf("s: %s\n",x)
        }()
    }
    time.Sleep(time.Second)
}

此代码产生以下输出:

s: foo
x: foo
s: bar
x: bar

s: bar
x: foo
s: bar
x: bar

假设这不是一些奇怪的编译器错误,我很好奇为什么a)s的值在goroutine版本中的解释与常规func调用中的不同,并且b)为什么将其分配给循环内的局部变量起作用?两种情况。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。