簡體   English   中英

通過通道和協程寫入切片:為什么切片最終為空

[英]Writing to a slice by a channel and a goroutine: why slice is eventually empty

我運行這個 function:

func Run() () {
    // This slice is going to be filled out by a channel and goroutine.
    vertices := make([]Vertex, 0)

    var wg sync.WaitGroup

    // Obtain a writer to fill out the vertices.
    writer := Writer(&wg, vertices)

    // Run an arbitrary logic to send data to writer.
    Logic(writer)

    // Stop the writer reading on the channel.
    close(writer)

    // Wait for the write to complete.
    wg.Wait()

    // See if vertices slice is actually filled out.
    DoublecheckVertices(vertices)
}

但最終,我的vertices切片是空的:

func DoublecheckVertices(vertices []Vertex) () {
    // Here I notice that `vertices` slice is actually empty :(

}

返回writer的 function 是這樣的:

func Writer(wg *sync.WaitGroup, vertices []Vertex) (chan<- []*Triangle3) {
    // External code writes to this channel.
    // This goroutine reads the channel and writes to vertices.
    writer := make(chan []*Triangle3)

    // Write by a goroutine.
    wg.Add(1)
    go func() {
        defer wg.Done()

        a := Vertex{}

        // Read from the channel and write them to vertices.
        for ts := range writer {
            for _, t := range ts {
                a.X = float32(t.V[0].X)
                a.Y = float32(t.V[0].Y)
                a.Z = float32(t.V[0].Z)
                vertices = append(vertices, a)
            }
        }
    }()

    return writer
}

誰能幫我弄清楚為什么我的vertices切片最終是空的?

日志

日志表明vertices切片實際上已被填充。 但由於某種原因,它在傳遞給DoublecheckVertices時為空。

                vertices = append(vertices, a)
                // This Log shows the slice is actually filled out:
                fmt.Printf("vertices len() is %v\n", len(vertices))

這似乎類似於“將切片作為 function 參數傳遞,並修改原始切片

如果您希望您的 goroutine 修改您在外部創建的切片,您需要一個指向該切片的指針:

func Writer(wg *sync.WaitGroup, vertices *[]Vertex) (chan<- []*Triangle3) {
    // External code writes to this channel.
    // This goroutine reads the channel and writes to vertices.
    writer := make(chan []*Triangle3)

    // Write by a goroutine.
    wg.Add(1)
    go func() {
        defer wg.Done()

        a := Vertex{}

        // Read from the channel and write them to vertices.
        for ts := range writer {
            for _, t := range ts {
                a.X = float32(t.V[0].X)
                a.Y = float32(t.V[0].Y)
                a.Z = float32(t.V[0].Z)
                *vertices = append(*vertices, a)  <=====
            }
        }
    }()

    return writer
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM