As mentioned by others, your variable i
is used inside the goroutines that you're created, but those goroutines could execute way in the future, once your loop is already done looping. At this point, the value of i
is not 5
, and all your go routines get kicked up, read the value of i
(as 5
) and continue on their merry way.
I believe FUZxxl mentioned the use of passing the value i
as an argument to the function. I think this is a good idea for rather complicated systems, specially if the function you're kicking a go routine for is not an inline closure. However, in most cases, I think it's a lot cleaner to just create a new temporary variable for each go routine:
http://play.golang.org/p/6dnkrEGfhn
func main() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
myi := i
go func() {
fmt.Println(myi)
wg.Done()
}()
}
wg.Wait()
}
The effect is the same, and it could be argued that it's a matter of preference, and it is. This is my preference :p