为了账号安全,请及时绑定邮箱和手机立即绑定

按顺序从 golang 频道中读取

按顺序从 golang 频道中读取

Go
凤凰求蛊 2022-03-03 19:51:57
我正在尝试通过 go 中的通道实现并行处理和通信。我基本上试图解决的是并行处理特定数据,并按顺序获得结果=>Chunk为此目的引入类型(见下文)。我只是为每个块处理创建新通道并将它们保存在切片中 => 期望在我之后迭代它们时被订购。我的程序的简化版本是(https://play.golang.org/p/RVtDGgUVCV):package mainimport (    "fmt")type Chunk struct {    from int    to   int}func main() {    chunks := []Chunk{        Chunk{            from: 0,            to:   2,        },        Chunk{            from: 2,            to:   4,        },    }    outChannels := [](<-chan struct {        string        error    }){}    for _, chunk := range chunks {        outChannels = append(outChannels, processChunk(&chunk))    }    for _, outChannel := range outChannels {        for out := range outChannel {            if out.error != nil {                fmt.Printf("[ERROR] %s", out.error)                return            }            fmt.Printf("[STDOUT] %s", out.string)        }    }}func processChunk(c *Chunk) <-chan struct {    string    error} {    outChannel := make(chan struct {        string        error    })    go func() {        outChannel <- struct {            string            error        }{fmt.Sprintf("from: %d to: %d\n", c.from, c.to), nil}        close(outChannel)    }()    return outChannel}我看到的输出是:[STDOUT] from: 2 to: 4[STDOUT] from: 2 to: 4然而,我希望看到的是:[STDOUT] from: 0 to: 2[STDOUT] from: 2 to: 4我在这里做错了什么?我没看到。
查看完整描述

1 回答

?
MMTTMM

TA贡献1869条经验 获得超4个赞

问题for在于main. 当您使用for range循环时,循环变量(chunk此处)被创建一次,并在每次迭代时被分配每个切片元素的副本。


当你调用 时processChunk(&chunk),你传递了这个循环变量的地址,并且这个变量的值随着每次迭代而改变。因此,该函数processChunk总是最终处理chunks循环中的最后一项,因为这是*chunkfor 循环完成后指向的内容。


要修复,请使用切片索引:


for i := 0; i < len(chunks); i++ {

    // pass chunk objects by indexing chunks

    outChannels = append(outChannels, processChunk(&chunks[i]))

}

修复代码: https: //play.golang.org/p/A1_DtkncY_


range 您可以在此处阅读更多信息。


查看完整回答
反对 回复 2022-03-03
  • 1 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信