I am unable to understand to why value of x increase even after scope end for varaiable ‘x’ in function foo(). It’s must reset to zero everytime I called a function. This this not happening why?
package main
import "fmt"
func main() {
a := foo()
fmt.Printf("%d
", a())
fmt.Printf("%d
", a())
fmt.Printf("%d
", a())
}
func foo() func() int {
var x int // value should reset to zero
return func() int {
x++
return x
}
}
Your function foo
returns a new function each time it's called. foo
doesn't just create that function though, it also allocates memory for a variable called x
of type int
. That variable is declared in the scope of foo
, and as such, the function foo
returns has access to that variable.
In essence, you're returning what is often referred to as a closure. A function that has access to a scope (variables) that are invisible to any other code. To visually represent this, maybe thing of it like this:
The function is what you return, the "environment record" it holds on to is the function body of foo
, and all of the variables declared there (in your case x
). The next environment record would be the package (variables declared outside functions with var
).
So what happens exactly:
a := foo()
Here, foo
allocates variable x
, and returns a function that holds on to this new variable.
a() // returns 1
a() // returns 2
The x
variable created by foo
is incremented, and its new value is returned each time.
Now that you know this, you should be able to work out what the output here will be:
a, b := foo(), foo() // creates 2 functions, 2 variables called x
_ = a()
_ = a()
fmt.Printf("a call returned %d
b call returned %d
", a(), b())
The output should be "a call returned 3 b call returned 1"