Is there a data race?
Yes, confirm it by running go run -race example.go
. The main goroutine writes i
, and the other goroutines read it without any synchronization. See Passing parameters to function closure; Why do these two for loop variations give me different behavior? and Register multiple routes using range for loop slices/map.
Why above code does not print anything?
Because when the main goroutine ends, your program ends as well. It does not wait for other non-main
goroutines to finish. See No output from goroutine
Fix
Make a copy of the loop variable, and use that in the closures, and use a sync.WaitGroup
to wait for the launched goroutines to end:
var wg sync.WaitGroup
for i := 0; i <= 9; i++ {
i2 := i
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(i2)
}()
}
wg.Wait()
This will output (try it on the Go Playground):
9
0
2
1
6
5
3
7
8
4
An alternative is to pass i
as a parameter to the launched function:
var wg sync.WaitGroup
for i := 0; i <= 9; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
}
wg.Wait()
Try this one on the Go Playground.