相关疑难解决方法(0)

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

考虑以下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 _, s := range []string{"foo", "bar"} {
        x := s
        go func() {
            fmt.Printf("s: %s\n", s)
            fmt.Printf("x: %s\n", x)
        }()
    }
    time.Sleep(time.Second)
}
Run Code Online (Sandbox Code Playgroud)

此代码生成以下输出:

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

s: bar
x: foo
s: bar
x: bar
Run Code Online (Sandbox Code Playgroud)

假设这不是一些奇怪的编译器错误,我很好奇为什么a)s的值在goroutine版本中然后在常规func调用中被解释不同而b)以及为什么将它分配给循环内部的局部变量两种情况.

closures go

5
推荐指数
2
解决办法
2422
查看次数

使用for循环进行并发,匿名函数意外行为

我已经找到了一种方法让代码按照我的意愿运行,但我想了解为什么它的行为如此,以便我对Go并发性的理解得到改善.

我正在测试sync.WaitGroup等待一些goroutines完成,因为我计划以这种方式多次上传到Amazon S3.

这是我原来的代码:

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()
}
Run Code Online (Sandbox Code Playgroud)

我惊讶地看到输出是:6, 6, 6, 6, 6.

而不是像:2, 4, 1, 5, 3.

由于循环甚至没有达到6,这对我来说没有任何意义.我后来将i变量作为参数传递给匿名函数,然后它表现得像我预期的那样.

为什么会这样?我不明白.

go

5
推荐指数
1
解决办法
670
查看次数

标签 统计

go ×2

closures ×1