So, What is Closure in Golang?

By Tour of Go definition, closure can be described as

Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is “bound” to the variables.

I modified the code a bit from the Tour of Go example:

As we can see, the adder function return an anonymous function with an int parameter and return an int. Beware that the sum variable is initiated in the adder function but outside of the anonymous function. In the main function, we store the anonymous function returned by adder, then after calling the stored function (adderFunc), every time we’re inputting an int in the parameter, the sum variable is added. It’s pretty unique though because it looks like the anonymous function should not “recognized” the sum variable right? But since it’s wrapped in the adder function, it forms a closure. This sum however only “saved” in the adderFunc. If we let say create a new one by calling adder(), the new created function will have its own sum.

Ok Now You Might Understand a Thing About Closure, But When Will We Use It?

Have you ever used a go routine just for make a simple function concurrent? in a nutshell you have a function process() and then you want to wrap things up like go func() { process() } (), more or less like this.

Ignore the last forever loop, it’s intended to keep the main function running

Let’s assume the process function takes some time (DB, API call, or anything in real application) and we simulate it to takes 50 milliseconds. We’re having an array of int for simplicity, in the real case it can be an array of struct / object from API call / DB / anything. Then let say we’re going to process it one by one concurrently so it won’t be blocking the whole process (faster). But if we run the program, rather than printing 0–9, this is what we get.

Unfortunately since the variable i is shared by go routine, the counter got to 10 first before the go routine process function use the variable. We can solve this by saving the i variable to temporary var, then use the temporary var for the goroutine function to closure the temp variable.

After changing the code, we’re having the expected result (all unique id from 0–9 is processed / printed).

There is also another alternative, we can declare the go routine to accept one parameter so the i at that time is copied to the anonymous go routine function parameter like this.

Testing it again, and it prints the correct result.

Be careful while using go routine and shared variable accross multiple go routine. Hope you find this article helpful, cheers :)

Fellow Software Engineer