LanguagesClosures and Anonymous Functions in Go

Closures and Anonymous Functions in Go

Go Programming ``

Golang and the Go programming language supports anonymous functions and these anonymous functions are also known as closures. Anonymous function are a special type of function that has no name and a closure can be thought of as a special type of anonymous function, although there is very little difference in practice.. Here, in this Go development tutorial, we will introduce the concept of anonymous functions with the help of appropriate Golang code examples.

What is an Anonymous Function in Go?

An anonymous function can also be called a function literal, lambda function, or a closure. The concept of a closure owes its origin to the mathematical evaluation of expression in the lambda-calculus. Technically, there is a subtle difference between an anonymous function and a closure: an anonymous function is a function without a name, while a closure is an instance of a function. However, to practically implement a closure in Golang, writing an anonymous function is the key.

Read: Understanding Functions in Go

How Do I Create a Closure in Go?

Anonymous functions enable us to write function literals that denote a function value within any expression. The writing scheme and syntax is very similar to their named counterpart (regular functions) except that here, the function has no name succeeding the func keyword. Therefore, if Go developers do not want to give a name to a function, then we can create an anonymous function. Since anonymous functions are also called function literals, lambda functions, or closures, we will use the name interchangeably.

Here is the syntax and example code for creating a closure in Go:

func (a, b int){ return a+b }

Note that such a function cannot be written as a stand alone, hence a variable is declared when the function is assigned, such as:

 
sum := func(a, b int) int { return a + b }
fmt.Println(sum(10, 20))

Additionally, the function is invoked as sum(10, 20). It can also be invoked directly at the time of definition, as follows:

sum := func(a, b int) int { return a + b }(10, 20)
fmt.Println(sum)

Here is another example, where we find the sum of integers – in this code example, we can write the lambda function as follows:

func() {
sum := 0
for i := 0; i < 100; i++ {
sum += i
}
}()

Note that the first parenthesis () after the func keyword is the list of parameters and the closure has no name. The body of the closure comprises the curly braces {} and the last pair of parenthesis () denotes the function call.

Read: Go Methods Explained

How to Return a Value from a Closure in Golang

As we have seen, a closure or an anonymous function can be created with or without parameters. But can we return a value from such a function? Here is an example of how to return a value from a closure in Go. Let us write a function that returns the next fibonacci number at each call:

package main

import "fmt"

func fibonacci() func() int {
		a, b := -1, 1
		return func() int {
		a, b = b, a+b
		return b
	}
}

func main() {
		fibo := fibonacci2()
		for i := 0; i < 10; i++ {
		fmt.Println(fibo())
	}
}

Go Functions That Return Another Function

Local variables that are declared have a limited scope and exist only within the block or function in which they are declared. When the variable loses its scope, it is flushed out of the memory. However, with the help of a closure, it is possible to hold on to the local variables even after the execution has moved out of the block. We can write a function that returns another function using Go closures. Here is an example:

func square() func(num int) int {
return func(num int) int {
return num * num
}
}

func mul(n1 int) func(n2 int) int {
return func(n2 int) int {
return n1 * n2
}
}

func main() {

// make an square function, give it a name f2, and call it:
f2 := square()
fmt.Printf("Call square for 3 gives: %v\n", f2(3))
// make a special mul function, n1 gets value 3:
f3 := mul(3)
fmt.Printf("The result is: %v\n", f3(3))
}

Read: Understanding Channels in Go

Passing Anonymous Functions as Arguments in Go

The following example program illustrates how an anonymous function can be passed as an argument to another function in Go. Also note that the anonymous function closes over variables to form a closure:

package main

import (
"fmt"
"math/rand"
"time"
)

func xyValues(f func(max int) (int, int)) {
x, y := f(35)
fmt.Println(x, y)
x, y = f(50)
fmt.Println(x, y)
}

func main() {
fn := func(max int) (int, int) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
x_axis := r.Intn(max)
y_axis := r.Intn(max)
return x_axis, y_axis
}

xyValues(fn)
x, y := fn(20)
fmt.Println(x, y)
}

In the above code example, the anonymous function is declared within the main function. It simply generates two random integers for x_axis and y_axis, within the range of a max value passed as a function argument and returned as the same. The anonymous function is assigned to the variable fn and passes the function value to another function named xyValues. The xyValues function receives a function, in turn, as an argument – namely the fn function argument.

A few things to note: in main the values of the anonymous function serve two purposes:

  • It calls the xyValues function by passing the function value as an argument.
  • Directly calls the function value by providing a value as an argument.

Final Thoughts on Go Closures and Anonymous Functions

A closure is a special feature derived from functional languages. Functions that can return another function – and functions that can take another function as an argument – are called higher order functions. This feature is very specific to functional programming languages, such as Go. With this in mind, know that a function can be treated like a value. As we can see, these characteristics of functional developer languages are offered by Golang. In fact, the use of closures is quite common in Go and often used with goroutines and channels.

Read: Introduction to Goroutines in Go

Latest Posts

Related Stories