【问题标题】:index out of range goroutine golang索引超出范围 goroutine golang
【发布时间】:2018-03-11 19:26:29
【问题描述】:

在 for 循环生成的 goroutine 中似乎不可能的索引超出范围错误

这是我正在执行的 go 代码。 问题是在 goroutine 中对 countlinks 调用的参数之一的评估中产生了索引超出范围错误。我们迭代的切片长度始终为 2。根据我对 go 中 for 循环的理解,i 永远不应计算为 2(在表达式grph.entryPoints[i] 中产生超出范围的索引),但它确实如此。请告诉我我有多疯狂。

func main() {
    grph := structures.ConfigGraphDefault()
    counter := structures.NewCounter()
    queue := structures.NewQueue()
    tracker := structures.NewTracker()
    fmt.Printf("entries: %v\nnodes: %v\n", grph.EntryPoints, grph.Nodes)
    wg := sync.WaitGroup{}
    fmt.Println(len(grph.EntryPoints))
    // this will always evaluate to 2
    l := len(grph.EntryPoints)
    for i := 0; i < l; i++ {
        wg.Add(1)
        go func() {
            fmt.Printf("index: %v, length of slice: %v\n", i, len(grph.EntryPoints))
            structures.CountLinks(&grph, counter, queue, tracker, grph.EntryPoints[i], i)
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Printf("counter: %v", counter.GetCounts())
}

【问题讨论】:

    标签: go goroutine


    【解决方案1】:

    i 确实变成了 2,但只是在循环的最后。但是因为你的 goroutine 函数关闭了i,所以它在 goroutine 启动时看不到 i 的值,而是在它执行时看到 i 的值。换句话说,你所有的 goroutine 共享同一个变量 i

    要解决此问题,一种方法是将i 复制到在循环体内声明的辅助变量。更好的方法是将它作为参数传递给 goroutine:

        go func(i int) {
            fmt.Printf("index: %v, length of slice: %v\n", i, len(grph.EntryPoints))
            structures.CountLinks(&grph, counter, queue, tracker, grph.EntryPoints[i], i)
            wg.Done()
        }(i)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      相关资源
      最近更新 更多