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

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

// Anonymous function (immediately invoked)
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

package main

import "fmt"

// Factory function that creates a counter.
func makeCounter(start int) func() int {
    count := start
    return func() int {
        count++ // count is captured by the closure
        return count
    }
}

// Factory function that creates a multiplier function.
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)
}

Notes

In Go, functions are treated as first-class values. 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 .