I have a file:
package main
import "fmt"
func
combinations(result chan []byte, len int, min byte, max byte) {
res := make([]byte,len)
for i := 0; i < len; i++ {
res[i] = min
}
result <- res
for true {
i := 0
for i = 0; i < len; i++ {
if res[i] < max {
res[i] = res[i] + 1;
break
} else {
res[i] = 32
}
}
result <- res
if(i == len) {
close(result)
return;
}
}
}
func
main() {
combination_chan := make(chan []byte)
go combinations(combination_chan, 2, 0, 5)
for next_combination := range combination_chan {
fmt.Printf("%x
",next_combination)
}
}
I expect this to print all possible combinations of 2 bytes between 0 and 5, IE:
0000
0100
...
0001
...
0505
However, it seems to skip every other value, and print the same value twice, IE:
0100
0100
0300
0300
...
Why would it be doing this? I've inserted prints before the 'result <- res' line, and those are all correct.
If we simplify a bit, a slice in Go is basically a pointer to an array, so by passing a slice that you still own and modify through a channel, you create a data race.
There is no telling if the contents of the slice are modified between the moment it is passed to the channel and the moment it is read from the channel by another goroutine.
So your whole algorithm leads to undefined behaviour, because you only pass the same contents over and over again while modifying them.
A solution in your case would be to copy the slice before sending it through the channel:
buf := make([]byte, len(res))
copy(buf, res)
result <- buf
See it running here: http://play.golang.org/p/ulLYy9Uqnp
Also, I don't recommend using len
as a variable name, because it can conflict with the len()
builtin function.