首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >循环时goroutines中的值不正确

循环时goroutines中的值不正确
EN

Stack Overflow用户
提问于 2017-03-07 18:43:53
回答 1查看 161关注 0票数 4

我已经通读了CommonMistakes,并通过-race标志运行了我的代码,但我似乎找不到这里的错误所在:

代码语言:javascript
运行
复制
package main

import (
    "fmt"
)

func main() {
    i := 1
    totalHashFields := 6
    for i <= totalHashFields {
        Combinations(totalHashFields, i, func(c []int) {
            fmt.Println("Outside goroutine:", c)
            go func(c []int) {
                fmt.Println("Inside goroutine:", c)
            }(c)
        })
        i++
    }
}

func Combinations(n, m int, emit func([]int)) {
    s := make([]int, m)
    last := m - 1
    var rc func(int, int)
    rc = func(i, next int) {
        for j := next; j < n; j++ {
            s[i] = j
            if i == last {
                emit(s)
            } else {
                rc(i+1, j+1)
            }
        }
        return
    }
    rc(0, 0)
}

(对于感兴趣的人,组合函数是一个组合algo )

以下是fmt.Println的一些输出:

代码语言:javascript
运行
复制
Outside goroutine: [0 1 4]
Inside goroutine: [5 5 5]
Outside goroutine: [0 1 2 3 4 5]
Inside goroutine: [5 5 5 5 5 5]

基本上,即使我将c作为参数传递给匿名go函数,该值也始终与此作用域之外的值不同。在上面的输出中,我期望2个“内部”值也分别为0 1 4和0 1 2 3 4 5。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-07 19:32:41

问题是你goroutine上的所有工作都是在distinc int切片上进行的,但是这些工作都共享一个公共的后备数组:在完成Combinations之后,s中的5将会充满主数组,你的c和s共享底层的后备数组。

但是您的goroutines只有在Combinations完成后才会开始执行,所以一旦它们启动,就会看到s的最终值只有5s。

在这里,像您一样传入切片没有什么帮助,因为这会生成c的正确副本,而不是支持数组的副本。

试一试

代码语言:javascript
运行
复制
Combinations(totalHashFields, i, func(c []int) {
    fmt.Println("Outside goroutine:", c)
    cpy := make([]int, len(c))
    copy(cpy, c)
    go func(c []int) {
        fmt.Println("Inside goroutine:", c)
    }(cpy)
})

来制作c语言的“深度拷贝”。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42646131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档