go - 从列表的大小循环,但在goroutine中未调用某些索引

标签 go channel goroutine

我有一个调度程序工作人员,我从列表的长度开始循环查找作业数,但是循环时有一些未调用的索引

    var members = []Member{
        {ID: 1, Is: true},
        {ID: 2, Is: false},
        {ID: 3, Is: true},
    }

    numOfWorker := 2
    var durationDelay time.Duration = 5000

    do, _ := worker.NewDispatcher(numOfWorker)
    ch := make(chan worker.MainJob, len(members))

    go func(jobs int) {
        for i := 0; i < jobs; i++ {
            newJob := &worker.NewJob{
                Final: ch,
                Do: func() worker.MainJob {
                    return worker.MainJob{ID: i , Message: "test"}
                },
            }
            do.Dispatch(newJob, durationDelay)
        }
        do.Await()
        close(ch)
    }(len(members))

    for v := range ch {
        fmt.Println(v)
    }
当我打印ch我懂了:
{1 test}
{3 test}
{3 test}
所以索引0和2不被调用,索引3是从哪里来的?成员的长度是3,所以叫做0 1 2我在这里犯错吗?
将newJob中的Do发送worker.MainJob的结果到Final像这样
Final <- Do()
最后是chan worker.MainJob,而Do是一个返回worker.MainJob的函数

最佳答案

您需要隐藏循环变量。
https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable

        for i := 0; i < jobs; i++ {
            i := i
            newJob := &worker.NewJob{
                Final: ch,
                Do: func() worker.MainJob {
                    return worker.MainJob{ID: i , Message: "test"}
                },
            }
            do.Dispatch(newJob, durationDelay)
        }

关于go - 从列表的大小循环,但在goroutine中未调用某些索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64083596/

相关文章:

hadoop - Flume 内存 channel 在启动时已满

go - 防止 main() 函数在 Goroutine 在 Golang 中完成之前终止

go - 奇怪的选择案例默认行为

SelectInt gorp 上的 MySQL NULL 值问题

go - 在 Golang 中,只有 case 子句(没有 case 表达式)和 default case 的 select 语句有什么作用?

ios - 解析 iOS API - 添加 channel

string - 为什么简单的 Go 应用程序占用大量内存

opengl - TEXTURE_2D_ARRAY 未渲染

arrays - 追加到结构内的结构数组

json - 为什么我的 Go 服务器不能正确解码从客户端发送的 JSON?