0
0
GoHow-ToBeginner · 3 min read

How to Use Closure in Go: Simple Guide with Examples

In Go, a closure is a function value that references variables from outside its body, capturing them to use later. You create a closure by defining a function inside another function, allowing the inner function to access and modify the outer function's variables even after the outer function has finished.
📐

Syntax

A closure in Go is created by defining an inner function that uses variables from its surrounding function. The inner function can access and modify these variables, and the outer function returns the inner function as a value.

  • Outer function: Defines variables and returns the inner function.
  • Inner function: Uses variables from the outer function, forming the closure.
  • Returned function: Can be called later, still accessing the captured variables.
go
func outer() func() int {
    x := 0
    return func() int {
        x++
        return x
    }
}
💻

Example

This example shows a closure that counts how many times it has been called by capturing and updating the variable x from the outer function.

go
package main

import "fmt"

func counter() func() int {
    x := 0
    return func() int {
        x++
        return x
    }
}

func main() {
    count := counter()
    fmt.Println(count()) // 1
    fmt.Println(count()) // 2
    fmt.Println(count()) // 3
}
Output
1 2 3
⚠️

Common Pitfalls

One common mistake is expecting the closure to capture the current value of a loop variable, but it actually captures the variable itself, which can lead to unexpected results.

Always create a new variable inside the loop to capture the current value if you want each closure to have its own copy.

go
package main

import "fmt"

func main() {
    funcs := []func(){ }

    for i := 0; i < 3; i++ {
        funcs = append(funcs, func() {
            fmt.Println(i) // All print 3, not 0,1,2
        })
    }

    for _, f := range funcs {
        f()
    }

    // Correct way:
    funcs2 := []func(){ }
    for i := 0; i < 3; i++ {
        v := i // new variable
        funcs2 = append(funcs2, func() {
            fmt.Println(v) // Prints 0,1,2
        })
    }

    for _, f := range funcs2 {
        f()
    }
}
Output
3 3 3 0 1 2
📊

Quick Reference

  • Closures capture variables by reference, not by value.
  • Use closures to maintain state between function calls.
  • Be careful with loop variables inside closures; create new variables to capture values.
  • Closures are useful for callbacks, generators, and encapsulating behavior.

Key Takeaways

A closure is a function that captures variables from its surrounding scope.
Closures keep access to captured variables even after the outer function returns.
Loop variables in closures can cause bugs; create new variables inside loops to avoid this.
Use closures to keep state or create flexible, reusable functions.