go - 迭代golang无缓冲 channel 时输出困惑

标签 go slice channel

迭代 golang 无缓冲 channel 时,我遇到了一个令人困惑的输出。
channel 定义为chan []int .
然后我将两个 slice 推送到 channel ,[0 1] 和 [2 3]。但是当我从 channel 中获取元素时,我得到了 [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]

最佳答案

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

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

关于go - 迭代golang无缓冲 channel 时输出困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61434798/

相关文章:

关闭 Go channel 时的​​ Go 竞争条件

go - K8s更改配置映射并更新应用程序日志级别

go - 检测导入包中的竞争条件

Python/Numpy 快速选择列表中第 n 个 block 的方法

python - 如何在 pandas 中查询 MultiIndex 索引列的值

go - 为什么当我在发件人端关闭时仍然会出现 "send on closed channel" panic ?

php - 使用golang解密用php openssl_encrypt加密的文件

go - 获取所有 map 值作为一个 slice ?

python - 如何在 pandas DataFrame 中设置给定索引级别的值

go - 同时将来自流的字节发送到两个目的地