Functions · Example 15
Closures
fmt slices stringsGo supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.
package main
import (
"fmt"
"slices"
"strings"
)intSeq returns another function, defined anonymously in its body. The returned function closes over the variable i to form a closure.
func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {nextInt captures its own i, which is updated each time we call it.
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())The state is unique to each closure: a new one starts over.
newInts := intSeq()
fmt.Println(newInts())Closures capture variables, not values. A change after the closure is made is visible inside it.
x := 1
show := func() { fmt.Println("x is", x) }
x = 2
show()Closures are handy as arguments, for example to sort by a custom rule.
words := []string{"banana", "Apple", "cherry"}
slices.SortFunc(words, func(a, b string) int {
return strings.Compare(strings.ToLower(a), strings.ToLower(b))
})
fmt.Println(words)A function literal can be called right where it is defined.
fmt.Println(func(a, b int) int { return a * b }(6, 7))
}$ go run ./15_closures 1 2 3 1 x is 2 [Apple banana cherry] 42