Anonymous Functions and Closures in Golang with Examples
Published on March 19, 2023
Golang allows functions to be assigned to variables, passed as argument to other functions and returned from other functions. Functions are first class citizens in Golang.
Anonymous functions
Anonymous function or function literal is a function without name. Anonymous functions useful for implementing functionality for short term use. See an example below:
// Create function literal - declare anonymous function
// and assign it to variable.
greeting := func() {
fmt.Println("Hello, world!")
}
// Call this function.
greeting()
Will output Hello, world!
. Note that greeting
is variable here.
Closures
Function literal has access to variables defined in enclosing function. These variables live as long as they are accessible. Function literals are closures in golang.
func NewCounterFunction() func() {
count := 0
return func() {
count++
fmt.Println(count)
}
}
func main() {
counter := NewCounterFunction()
counter() // 1
counter() // 2
counter2 := NewCounterFunction()
counter2() // 1
}
Function NewCounterFunction
declares variable count
, creates and returns anonymous function as a result.
This function has access to count
variable, it will increment and prints current value of count
, every time when you call it.
Inside the main function we create function literal counter
, call it two time and see call sequence number.
Also, we create second counter counter2
, it starts output from 1
, because it refers to new instance of counter
.
These two anonymous function work independent and does not share variables between.
Example 1. Find element in a slice
Following example will show usage of Find
function from sort
package for seeking element in a slice.
Syntax:
func Find(n int, cmp func(int) int) (i int, found bool)
Find
function accepts two arguments:
n int
- max index in seeking slicecmp func(int) int
- comparator, anonymous function.
package main
import (
"fmt"
"sort"
)
func main() {
// slice should be sorted!
elements := []int{1, 2, 3, 4, 5}
needle := 4
idx, found := sort.Find(len(elements), func(i int) int {
if needle < elements[i] {
return -1
}
if needle > elements[i] {
return 1
}
return 0
})
fmt.Println(idx, found) // 3 true
}
Anonymous function declared within main function and has access to elements
and needle
variables.
Inline function passing can be replaced with passing function literal, as shown below.
comparatorFn := func(i int) int {
if needle < elements[i] {
return -1
}
if needle > elements[i] {
return 1
}
return 0
}
idx, found := sort.Find(len(elements), comparatorFn)
Checkout how closures help implement functional options pattern →