I am seeing incorrect values in the functions run as goroutines. They don't seem to be capturing the values from the scope in which they were invoked unless copied into new variables.
http://play.golang.org/p/YZYi-IVuYm
vs.
http://play.golang.org/p/z88G99XSi6
You either need to re-assign the variable in the local context so that the closure can capture the values:
http://play.golang.org/p/-NO4S4qCZf
package main
import "fmt"
import "time"
func main() {
l := []int{1, 2, 3}
for idx, item := range l {
theIdx, theItem := idx, item
go func() {
fmt.Println(theIdx, theItem)
}()
}
time.Sleep(time.Second)
}
or you pass the values to the goroutine and add parameters to the function
http://play.golang.org/p/5gNToDWSQR
package main
import "fmt"
import "time"
func main() {
l := []int{1, 2, 3}
for idx, item := range l {
go func(idx, item int) {
fmt.Println(idx, item)
}(idx, item)
}
time.Sleep(time.Second)
}
This is expected, and documented in the Go "Common Mistakes" page. You can argue with the design decision, but it is a known effect.
A recommended way to do this is to pass the values in as parameters.
By the time the first goroutine is executed, idx
and item
have already been overwritten with the next values. As the routines are executed within the same scope, you get the new values.
It does make sense, in hindsight.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With