【问题标题】:Goroutine inside for loop takes only the last value of slice [duplicate]for 循环中的 Goroutine 只取 slice 的最后一个值
【发布时间】:2021-12-27 06:46:06
【问题描述】:

谁能向我解释这种行为?

package main

import (
    "fmt"
    "time"
)

func main() {
    a := []int64{1, 2, 3, 4, 5}
    for _,v := range a {
        go func(){
            fmt.Println("value is ", v)
        }()
            
    }
    time.Sleep(2*time.Second)
    
}

此代码打印以下输出。

value is  5
value is  5
value is  5
value is  5
value is  5

为什么没有传入参数时,goroutine 只取 slice 中的最后一个值?

编辑:我只想知道程序是如何执行的。每个 goroutine 都具有相同的值,但为什么它总是最后一个值? (疑问:goroutine是不是只有在slice中的所有元素都循环完后才会执行?)

【问题讨论】:

  • 只有一个v,它会在循环的每次迭代中改变值。您也可能在这里同时阅读和修改v,这是一个竞争条件。所以实际结果不会很好定义。
  • v的值作为参数值传递给goroutine
  • 重复。甚至包含在官方常见问题解答中。

标签: for-loop go concurrency goroutine


【解决方案1】:

因为每个 goroutine 都持有相同的变量 v。 如果要取不同的silce值,请这样做:

func main() {
a := []int64{1, 2, 3, 4, 5}
for _,v := range a {
    v2 := v
    go func(){
        fmt.Println("value is ", v2)
    }()

}
time.Sleep(2*time.Second)

}

输出是:

value is  1
value is  2
value is  3
value is  4
value is  5

【讨论】:

    猜你喜欢
    • 2015-04-08
    • 2016-03-03
    相关资源
    最近更新 更多