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

迭代golang无缓冲通道时混淆输出,go,slice,channel,Go,Slice,Channel,在迭代golang无缓冲通道时,我遇到了令人困惑的输出。 频道定义为chan[]int。 然后我将两个切片推送到通道[01]和[23]。但当我从通道中获取元素时,得到了[23]和[23]。为什么会发生这种情况 package main import "fmt" import "sync" func producer(jobs chan []int, wg *sync.WaitGroup) { defer wg.Done() a := make([]int, 2) i

在迭代golang无缓冲通道时,我遇到了令人困惑的输出。 频道定义为
chan[]int
。 然后我将两个切片推送到通道[01]和[23]。但当我从通道中获取元素时,得到了[23]和[23]。为什么会发生这种情况

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: [2 3]
job: [2 3]

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


您可以为每个迭代创建一个新切片并发送该切片。每个片将有一个单独的备份阵列,并将按照您的预期工作

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

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()
}
主程序包
输入“fmt”
导入“同步”
func制作人(jobs chan[]int,wg*sync.WaitGroup){
推迟工作组完成()
a:=make([]整数,2)
a[0]=1
a[1]=2

jobs add
a=make([]int,2)
jobs编译错误之后,我认为需要修改第29行(从
go producer(ch,&wg)
go producer(jobs,&wg)
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()
}
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()
}