In this block of code below, I expect the output to be 0, 1, 2, 3,..., 9. However, only the output 10, 10,...,10 is produced.
package main
import "fmt"
func adder() []func() {
out := []func(){}
for i := 0; i < 10; i++ {
out = append(out, func() { fmt.Println(i) })
}
return out
}
func main() {
out := adder()
for i := 0; i < 10; i++ {
out[i]()
}
}
My mental model suggests that a new function is generated and stored every time in the for-loop, but it doesn't seem to be the case. Is there a solution to generating new functions without modifying the signature (no parameters or global variables) but still keeping the current value of i?
A new function is created every iteration, but they all close over the same variable, i
. That variable is updated with every iteration until the last, so when you go through and execute all those functions, they all refer to the same i
, with the same value, 10
.
If you don't want that behavior, you must not close over the loop variable:
for i := 0; i < 10; i++ {
temp := i
out = append(out, func() { fmt.Println(temp) })
}