迭代golang无缓冲通道时输出混乱

迭代 golang 无缓冲通道时,我遇到了一个令人困惑的输出。通道定义为chan []int。然后我将两个切片推送到通道,[0 1] 和 [2 3]。但是当我从频道中获取元素时,我得到了 [2 3] 和 [2 3]。为什么会这样?


package main


import "fmt"

import "sync"


func producer(jobs chan []int, wg *sync.WaitGroup) {

    defer wg.Done()


    a := make([]int, 2)

    index := 0

    for i := 0; i < 4; i++ {

        a[index] = i

        index++

        if index == 2 {

            index = 0

            fmt.Printf("a: %+v\n", a)

            jobs <- a

        }    

    }


    close(jobs)

}


func main() {

    var wg sync.WaitGroup

    wg.Add(1)

    jobs := make(chan []int, 2)

    go producer(jobs, &wg)

    for job := range jobs {

        fmt.Printf("job: %+v\n", job)

    }


    wg.Wait()

}

预期输出:


a: [0 1]

a: [2 3]

job: [0 1]

job: [2 3]

实际输出:


a: [0 1]

a: [2 3]

job: [2 3]

job: [2 3]


茅侃侃
浏览 97回答 2
2回答

白猪掌柜的

切片包含指向支持数组的指针。当您通过通道发送切片时,您发送的是对该支持数组的引用,因此在接收端,即使您多次读取切片,您实际上也引用了同一个共享支持数组。您可以为每次迭代创建一个新切片并将其发送。每个切片都有一个单独的后备数组,并且将按您的预期工作。

汪汪一只猫

稍微修改您的程序以便更好地阅读。package mainimport "fmt"import "sync"func producer(jobs chan []int, wg *sync.WaitGroup) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; a := make([]int, 2)&nbsp; &nbsp; a[0] = 1&nbsp; &nbsp; a[1] = 2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobs <- a&nbsp; &nbsp;//We are passing memory location of slice ( is nature of slice ), so the values changing next line will affect here too&nbsp; &nbsp; a[0] = 2&nbsp; &nbsp; a[1] = 3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jobs <- a&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; close(jobs)}func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; jobs := make(chan []int, 2)&nbsp; &nbsp; go producer(jobs, &wg)&nbsp; &nbsp; for job := range jobs {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("job: %+v\n", job)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}我用 Array 尝试过的相同程序,然后我们将得到您期望的结果,请参见下面的代码package mainimport "fmt"import "sync"func producer(jobs chan [2]int, wg *sync.WaitGroup) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp;var a[2]int&nbsp; &nbsp; a[0] = 1&nbsp; &nbsp; a[1] = 2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobs <- a&nbsp; &nbsp;&nbsp; &nbsp; a[0] = 2&nbsp; &nbsp; a[1] = 3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jobs <- a&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; close(jobs)}func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; jobs := make(chan [2]int)&nbsp; &nbsp; go producer(jobs, &wg)&nbsp; &nbsp; for job := range jobs {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("job: %+v\n", job)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go