For clarity, I'll assign names to both functions:
func makeEvenGenerator() func() uint { // call this "the factory" i := uint(0) return func() (ret uint) { // call this "the closure" ret = i i += 2 return } }
factory returns a closure - functions are citizens of the first class in Go, that is, they can be right expressions, for example:
f := func() { fmt.Println("f was called"); } f() // prints "f was called"
In your code, closure wraps around the factory context, this is called lexical scope. This is why the variable i is available inside the closure, not as a copy, but as a reference to i .
Closing uses a named return value called ret . This means that inside the closure you implicitly declared ret and at the point return , any value of ret will be returned.
This line:
ret = i
will assign the current value of i to ref . He will not change i . However, this line:
i += 2
changes the value of i the next time a closure is called.
Here you will find a small closing example that I wrote for you. This is not very useful, but, in my opinion, illustrates very well the scope, purpose and use of closures:
package main import "fmt" func makeIterator(s []string) func() func() string { i := 0 return func() func() string { if i == len(s) { return nil } j := i i++ return func() string { return s[j] } } } func main() { i := makeIterator([]string{"hello", "world", "this", "is", "dog"}) for c := i(); c != nil; c = i() { fmt.Println(c()) } }