[Golang] Pass Reference to Goroutine While range Slice
Something strange happened when I tried to pass references to goroutines while range slice. Consider the following code:
package main
import (
"fmt"
)
func printNumber(number *int, c chan int) {
fmt.Println(*number)
c <- 1
}
func main() {
numbers := []int{1, 2, 3}
c := make(chan int)
for _, number := range numbers {
go printNumber(&number, c)
}
// wait all goroutines to finish
for i := 0; i < len(numbers); i++ {
<-c
}
}
The output in the console is:
3
3
3
I cannot figure out what happened. It supposed to be something like:
1
3
2
But I got all 3! This is not what I want. I cannot figured out what's wrong, so I tried some googling [2], and the answer in [3] gived me solution.
Solution: use the array index instead of the value
Change the code of range to the following:
for index, _ := range numbers {
go printNumber(&numbers[index], c)
}
And now everything works as expected! (Although I still do not know why!)
Tested on:
- Ubuntu Linux 17.10, Go 1.9.3.
- Go Playground
References:
[1] | [Golang] Wait For Goroutine to Finish |
[2] |
[3] | pointers - golang range references instead values - Stack Overflow |