Golang: Closures
Tags: go
Published: 2022-08-18 13:18:04

## Introduction

In the previous part of the series, we covered [anonymous functions](https://meetgor.com/golang-anonymous-functions/) and in this section, we will look into `closures` which are quite a cool concept for various things. Closures are basically a function that returns a function instead of a value, so basically we will leverage anonymous functions for creating closures.

## Simple Closures

A simple closure can be constructed for understanding how we can use closures in golang. We will return a function from a function, that is a simple closure. So, in the below code example, we have created a function `gophy()` which takes no parameters but returns a function that returns a `string`.  The function simply returns an anonymous function that returns a string.

We will initialize the variable `g` that is assigned to the function `gophy` which will simply return a function call. We are not calling the function simply returning the call to the function `gophy` that has the return value as the anonymous function. We will simply have the function in the variable `g` rather than the simple value string. So we will have to call the `g` variable for actually returning the string.

```go
package main

import "fmt"

func gophy() func() string{
  return func() string{
    return "Hello, Gophers!"
  }
}

func main() {

	// using clousure/anonymous function to return a value
	// that value can be assigned to the variable
	g := gophy()
	fmt.Println(g())
}

```

```
$ go run simple.go
Hello, Gophers!

```

So, that is how we can call the function `g` that will return a string, so we have the function body stored in the variable `g`. We can call it as many times as we want.

## Variable Scope in Closures

We can even use variables that will remain in the function scope once it is initialized. So, let’s say we have a function that will increment the counter, but if we want to keep the counter the same throughout the program, we might have to use a global variable so as to maintain the context, but with closures, we will retain the value once we have initialized the function call.

In the below example, we are creating the function `incrementer` that is a closure with int as the return type. We are initializing the variable `counter` that will be acting as the counter in the program, the function returns an anonymous function that will increment the counter and return it.

Here, when we create an instance of the `increment` function it basically initializes the `counter` to `0` and returns the anonymous function as a call. Now, `c` will act as a function that has the counter variable bound to it and we can call `c` that will, in turn, call the anonymous function keeping the scope of the `counter` variable.  So, each time we call the function `c` it will increment the counter and thus we keep the counter inside the scope of the function `incrementer` in the `c` variable.

```go
package main

import "fmt"

func inrementer() func() int{
  counter := 0
  return func() int{
    counter += 1
    return counter
  }
}

func main() {

  c := inrementer()

  fmt.Println(c())
  fmt.Println(c())
  fmt.Println(c())
  fmt.Println(c())
  fmt.Println(c())

}

```

```
$go run simple.go
1
2
3
4
5

```

If we want to extend the functionality,  we can even assign the function call `c()` to a variable and access the returned value which will be the current state of the counter.

We can even use different scope or closures tied to a particular function, that is we can bind data to a different instances of a closure.

```go
package main

import "fmt"

func inrementer() func() int{
  counter := 0
  return func() int{
    counter += 1
    return counter
  }
}

func main() {

  c1 := inrementer()

  fmt.Println(c1())
  fmt.Println(c1())
  fmt.Println(c1())

  c2 := inrementer()

  fmt.Println(c2())
  fmt.Println(c2())
  fmt.Println(c2())
  fmt.Println(c2())

}

```

```
$go run simple.go
1
2
3
1
2
3
4

```

Here we have `c1` and `c2` forming different closures and thereby we can have different scopes of the variables associated with it. The variable is bound to the instance it which was initialized, so we can see the different closure instances having different values.

## Factorial of a function with Closures

We can create some interesting programs with closures, we will implement the calculation of factorial with closures in golang.

This will be a `factorial` function that returns an anonymous function with the return type as `int`. The function will initialize the variable `fact` which will store the actual factorial value and `n` as the initial number for calculating the factorial of it.

Inside the anonymous function, we will calculate the factorial and increment the number and simply return the factorial value from the function. The `fact` variable will contain the factorial of the number n, so here we can leverage the use of closures as we will maintain the state of the variable `fact` and `n` from the previous calls or the initialization of the function.

Inside the `main` function, we have created the `f` variable and called the `factorial` function, so that will initialize the `fact` and `n` of the variable and thereby returning the anonymous function call. Now we can call the variable `f` as many times as we want that will simply return the factorial of the number incremented each time we call the function.

```go
package main

import "fmt"

func factorial() func() int{
	fact, n := 1, 1
	return func() int{
    fact = fact * n
    n += 1
		return fact
	}
}

func main() {

  f := factorial()
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())
  fmt.Println(f())

}

```

```
$ go run simple.go
1
2
6
24
120

```

So, we can see that the factorial is getting printed for each call and the number is being incremented at each call.

So that's the basics of closures in golang, we can use closures to keep the content secured and encapsulated from different function calls. We can bind data with closures, with the help of anonymous functions a closure can be constructed and data can be bound to a particular function called scope.

That's it from this part. Reference for all the code examples and commands can be found in the [100 days of Golang](https://github.com/mr-destructive/100-days-of-golang/tree/main/scripts/closures/man.go) GitHub repository.

## Conclusion

From this post, we could understand the fundamentals of closures in golang. The basic concept of closures in golang was understood with a few examples. Thank you for reading, if you have any queries or feedback please leave them in the comments or on my social handles. Happy Coding :)