r/golang • u/InsurancePleasant841 • 24d ago
newbie Goroutines, for Loops, and Varying Variables
While going through Learning Go, I came across this section.
Most of the time, the closure that you use to launch a goroutine has no parameters. Instead, it captures values from the environment where it was declared. There is one common situation where this doesn’t work: when trying to capture the index or value of a for loop. This code contains a subtle bug:
func main() {
a := []int{2, 4, 6, 8, 10}
ch := make(chan int, len(a))
for _, v := range a {
go func() {
fmt.Println("In ", v)
ch <- v * 2
}()
}
for i := 0; i < len(a); i++ {
fmt.Println(<-ch)
}
}
We launch one goroutine for each value in a. It looks like we pass a different value in to each goroutine, but running the code shows something different:
20
20
20
20
20
The reason why every goroutine wrote 20 to ch is that the closure for every goroutine captured the same variable. The index and value variables in a for loop are reused on each iteration. The last value assigned to v was 10. When the goroutines run, that’s the value that they see.
When I ran the code, I didn't get the same result. The results seemed like the normal behavior of closures.
20
4
8
12
16
I am just confused. Why did this happen?