goroutine仅通过通道传递值的一半

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.