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

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

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

Go
茅侃侃 2022-06-01 12:21:49
迭代 golang 无缓冲通道时,我遇到了一个令人困惑的输出。通道定义为chan []int。然后我将两个切片推送到通道,[0 1] 和 [2 3]。但是当我从频道中获取元素时,我得到了 [2 3] 和 [2 3]。为什么会这样?package mainimport "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]
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

切片包含指向支持数组的指针。当您通过通道发送切片时,您发送的是对该支持数组的引用,因此在接收端,即使您多次读取切片,您实际上也引用了同一个共享支持数组。

您可以为每次迭代创建一个新切片并将其发送。每个切片都有一个单独的后备数组,并且将按您的预期工作。


查看完整回答
反对 回复 2022-06-01
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

稍微修改您的程序以便更好地阅读。


package main


import "fmt"

import "sync"


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

    defer wg.Done()


    a := make([]int, 2)

    a[0] = 1

    a[1] = 2

            jobs <- a   //We are passing memory location of slice ( is nature of slice ), so the values changing next line will affect here too

    a[0] = 2

    a[1] = 3

           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()

}

我用 Array 尝试过的相同程序,然后我们将得到您期望的结果,请参见下面的代码


package main


import "fmt"

import "sync"


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

    defer wg.Done()


   var a[2]int

    a[0] = 1

    a[1] = 2

            jobs <- a   

    a[0] = 2

    a[1] = 3

           jobs <- a  

    


    close(jobs)

}


func main() {

    var wg sync.WaitGroup

    wg.Add(1)

    jobs := make(chan [2]int)

    go producer(jobs, &wg)

    for job := range jobs {

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

    }


    wg.Wait()

}


查看完整回答
反对 回复 2022-06-01
  • 2 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

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