Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Go Dictionary
  3. Closures / Anonymous Functions

Closures / Anonymous Functions

Since: Go 1.0(2012)

In Go, functions are first-class values — you can assign them to variables, pass them as arguments, or return them from other functions. A closure is a function that "closes over" the variables in scope at the time it is defined, and is a fundamental pattern in functional programming.

Syntax

func() {
    // body
}()

// Assign to a variable.
add := func(a, b int) int {
    return a + b
}
result := add(3, 4) // 7

// Closure (captures a variable from the outer scope)
counter := 0
increment := func() int {
    counter++ // references the outer variable counter
    return counter
}

// Higher-order function that returns a function (closure factory)
func makeAdder(x int) func(int) int {
    return func(y int) int {
        return x + y // x is captured by the closure
    }
}

Common Closure Patterns

PatternDescription
Immediately invoked functionDefines and calls a function in one expression. Useful for initialization and scope isolation.
State encapsulationThe closure holds a variable that cannot be accessed from outside, achieving private state.
Factory functionGenerates and returns a function pre-configured with a given parameter.
CallbackUses an anonymous function when passing a function as an argument.

Sample Code

sample_closure.go
package main

import "fmt"

func makeCounter(start int) func() int {
    count := start
    return func() int {
        count++ // count is captured by the closure
        return count
    }
}

func multiplier(factor int) func(int) int {
    return func(n int) int {
        return n * factor
    }
}

// Higher-order function that accepts a function as an argument.
func apply(nums []int, fn func(int) int) []int {
    result := make([]int, len(nums))
    for i, n := range nums {
        result[i] = fn(n)
    }
    return result
}

func main() {
    // Encapsulate state with closures.
    counter1 := makeCounter(0)
    counter2 := makeCounter(10) // each has its own independent state
    fmt.Println(counter1()) // 1
    fmt.Println(counter1()) // 2
    fmt.Println(counter2()) // 11
    fmt.Println(counter1()) // 3 (not affected by counter2)

    fmt.Println()

    // Generate customized functions using a factory.
    double := multiplier(2)
    triple := multiplier(3)
    nums := []int{1, 2, 3, 4, 5}
    fmt.Println("doubled:", apply(nums, double))
    fmt.Println("tripled:", apply(nums, triple))

    fmt.Println()

    // Pass an anonymous function inline.
    fmt.Println("squared:", apply(nums, func(n int) int {
        return n * n
    }))

    // Initialization with an immediately invoked function
    result := func(a, b int) int {
        return a + b
    }(100, 200)
    fmt.Println("immediately invoked result:", result)
}

This produces the following output:

go run closure.go
1
2
11
3

doubled: [2 4 6 8 10]
tripled: [3 6 9 12 15]

squared: [1 4 9 16 25]
immediately invoked result: 300

Notes

In Go, functions are treated as first-class values — meaning they can be assigned to variables, passed as arguments, and returned from other functions. Because a closure holds a reference to the captured variable, any changes made through the closure affect the original variable. This behavior enables a design similar to object-oriented encapsulation.

A well-known bug occurs when launching goroutines inside a loop: the closure may not capture the loop variable correctly. Pass the loop variable as an argument to the closure, or create a local copy inside the loop body. Note that Go 1.22 changed how loop variables are scoped.

For variadic arguments, see Variadic Arguments. For combining closures with goroutines, see Goroutine.

If you find any errors or copyright issues, please .