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]
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.
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.
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.
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With