Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a slice into a channel

Tags:

go

I'm trying to pass the results of munging a slice into a channel. Here's the obviously broken version. I've tried a few ways of doing it that don't seem to work well. I'm looking for an idiomatic way of tackling this.

func gen() <-chan []int {
    c := make(chan []int)

    go func(c chan []int) {
        defer close(c)
        s := []int{0, 1, 2, 3}

        for i := 0; i < len(s); i++ {
            s[i] = -1
            c <- s
        }
    }(c)

    return c

}

func main() {
    for s := range gen() {
        fmt.Println(s)
    }
}

Result:

[-1 -1 2 3]
[-1 -1 2 3]
[-1 -1 -1 -1]
[-1 -1 -1 -1]
like image 554
magahet Avatar asked Jul 11 '14 18:07

magahet


People also ask

Is slice pass by reference?

It is a common belief that slices are passed by reference, in fact, the following example will print [b,b] and [b,b] even if the slice was initialized to [a,a] since it got modified during the execution of the literal function and the change is visible to the main.

What is buffered channel in Golang?

Buffered channels allows to accept a limited number of values without a corresponding receiver for those values. It is possible to create a channel with a buffe. Buffered channel are blocked only when the buffer is full. Similarly receiving from a buffered channel are blocked only when the buffer will be empty.

What is difference between Array and slice in Golang?

Slices in Go and Golang The basic difference between a slice and an array is that a slice is a reference to a contiguous segment of an array. Unlike an array, which is a value-type, slice is a reference type. A slice can be a complete array or a part of an array, indicated by the start and end index.


1 Answers

It does not work because the underlying array is the same. So you are modifying the same memory.

Here is a working example. Copy the memory at each round.

http://play.golang.org/p/OXfKVg8ZlZ

package main

import "fmt"

func gen() <-chan []int {
    c := make(chan []int)

    go func(c chan []int) {
        defer close(c)

        s := []int{0, 1, 2, 3}
        for i := 0; i < len(s); i++ {
            s[i] = -1
            newSlice := make([]int, len(s))
            copy(newSlice, s)
            c <- newSlice
        }
    }(c)

    return c

}

func main() {
    for s := range gen() {
        fmt.Println(s)
    }
}

Output

[-1 1 2 3]
[-1 -1 2 3]
[-1 -1 -1 3]
[-1 -1 -1 -1]
like image 94
fabrizioM Avatar answered Oct 21 '22 22:10

fabrizioM