Why can I do the following to define an iterator in Go:
func f() func() int {
i := 1
return func() int {
i++
return i
}
}
but this will result in a variable not used error (i
is not used)?
func f() func() int {
i := 1
return func() (i int) {
i++
return
}
}
main function:
func main() {
iter := f()
fmt.Println(iter())
fmt.Println(iter())
fmt.Println(iter())
fmt.Println(iter())
}
To me both versions do exactly the same: They use f
as an iterator. f
makes use of closures (more specifically i
). The first version explicitly returns an incremented i
and the second implicitly, by referring to it via a named return type.
To me both versions are the same, so why do I get an error?
In the second case, the return value (i int)
shadows the outer declaration i := 1
. So it's this first i
that is unused. This means the second example isn't a closure at all.
From a scoping standpoint, your second example is the same as:
func f() func() int {
i := 1
return func(i int) int {
i++
return
}
}
In this case, it should be clear that the inner i
is distinct, and shadows the outer one.