Go closure is a nested function that allows us to access variables of the outer function even after the outer function is closed.
Before we learn about closure, let's first revise the following concepts:
In Go, we can create a function inside another function. This is known as a nested function. For example,
In the above example, we have created an anonymous function inside the greet() function.
Here, var displayName = func() {...} is a nested function. The nested function works similar to the normal function. It executes when displayName() is called inside the function greet().
We can create a function that returns an anonymous function. For example,
Output
In the above example, we have created the greet() function.
Here, func() before the curly braces indicates that the function returns another function.
Also, if you look into the return statement of this function, we can see the function is returning a function.
From main(), we call the greet() function.
Here, the returned function is now assigned to the g1 variable. Hence, g1() executes the nested anonymous function.
As we have already discussed, closure is a nested function that helps us access the outer function's variables even after the outer function is closed. Let's see an example.
Output
In the above example, we have created a function named greet() that returns a nested anonymous function.
Here, when we call the function from main().
The returned function is now assigned to the message variable.
At this point, the execution of the outer function is completed, so the name variable should be destroyed. However, when we call the anonymous function using
we are able to access the name variable of the outer function.
It's possible because the nested function now acts as a closure that closes the outer scope variable within its scope even after the outer function is executed.
Let's see one more example to make this concept clear for you.
Output
In the above example,
This code executes the outer function calculate() and returns a closure to the odd number. That's why we can access the num variable of calculate() even after completing the outer function.
Again, when we call the outer function using
a new closure is returned. Hence, we get 3 again when we call odd2().
As we see in the previous example, a new closure is returned every time we call the outer function. Here, each returned closure is independent of one another, and the change in one won't affect the other.
This helps us to work with multiple data in isolation from one another. Let's see an example.
Output
In the above example, the displayNumbers() function returns an anonymous function that increases the number by 1.
Inside the main() function, we assign the function call to num1 and num2 variables.
Here, we first call the closure function using num1(). In this case, we get outputs 1, 2, and 3.
Again, we call it using num2(). In this case, the value of the number variable doesn't start from 3; instead, it starts from 1 again.
This shows that the closure returned from displayNumbers() is isolated from one another.