按顺序从 golang 频道中读取

我正在尝试通过 go 中的通道实现并行处理和通信。


我基本上试图解决的是并行处理特定数据,并按顺序获得结果=>Chunk为此目的引入类型(见下文)。


我只是为每个块处理创建新通道并将它们保存在切片中 => 期望在我之后迭代它们时被订购。


我的程序的简化版本是(https://play.golang.org/p/RVtDGgUVCV):


package main


import (

    "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

我在这里做错了什么?我没看到。


凤凰求蛊
浏览 123回答 1
1回答

MMTTMM

问题for在于main. 当您使用for range循环时,循环变量(chunk此处)被创建一次,并在每次迭代时被分配每个切片元素的副本。当你调用 时processChunk(&chunk),你传递了这个循环变量的地址,并且这个变量的值随着每次迭代而改变。因此,该函数processChunk总是最终处理chunks循环中的最后一项,因为这是*chunkfor 循环完成后指向的内容。要修复,请使用切片索引:for i := 0; i < len(chunks); i++ {&nbsp; &nbsp; // pass chunk objects by indexing chunks&nbsp; &nbsp; outChannels = append(outChannels, processChunk(&chunks[i]))}修复代码: https: //play.golang.org/p/A1_DtkncY_range 您可以在此处阅读更多信息。
打开App,查看更多内容
随时随地看视频慕课网APP