for-loop - 字符串 slice 的范围不一致

标签 for-loop go closures goroutine for-range

这段代码:

import "fmt"
import "time"
func main() {
    string_slice:=[]string{"a","b","c"}

    for _,s:=range string_slice{
        go func(){
            time.Sleep(1*time.Second)
            fmt.Println(s)
        }()
    }

    time.Sleep(3*time.Second)
}

产生输出“c c c”,而这段代码:

import "fmt"
func main() {
    string_slice:=[]string{"a","b","c"}

    for _,s:=range string_slice{
        s="asd"
        fmt.Println(s)
    }
    fmt.Println(string_slice)
}

产生输出“[a b c]”

第一个建议 for range 迭代引用(它不应该),第二个建议它迭代值的副本(它应该)。

为什么第一个不产生输出“a b c”?

最佳答案

当使用 goroutine 时,你必须假设它会并行运行。所以在这种情况下可能会出现 'c c c' 以及 'b b b' 或 'a a a'

运行此代码的 3 次:

for _,s:=range string_slice \\run t0, t1, t2 

将发送运行此代码的 3 次:

go func(){
  fmt.Println(s)
}()//send in t0, t1, t2

因此,根据示例,func() 可能会在 t2 开始运行。在这种情况下,结果将为 'c c c',因为 s 等于最新值 (string_slice[2])。

解决方案是通过 func params 复制值:

for _, s := range string_slice{
    go func(x string){
        time.Sleep(1*time.Second)
        fmt.Println(x)
    }(s)
}

或者每次迭代创造新的值(value)

//creating new value per iteration
for i := range string_slice{
    s := string_slice[i]
    go func(){
        time.Sleep(1*time.Second)
        fmt.Println(s)
    }()
}

参见工作 https://play.golang.org/p/uRD6Qy6xSw

关于for-loop - 字符串 slice 的范围不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45941794/

相关文章:

java - 在for循环中添加列表/数组元素,java12

javascript - 在 ng-repeat 中生成 ng-model

go pprof 在不同的平台上不起作用

closures - "this"在 TypeScript 的方法调用中?

javascript - For循环条件问题

r - 条件列创建(水平和垂直条件)

go - 无法安装 Revel(无法识别的导入路径)

go - rpc.ServerCodec 还在服务吗?

python - Ruby 的 yield 在 Python 中的等价物是什么?

当我将类移动到框架中时,Swift 尾随闭包停止工作