🎓 A1Learner
🔍
0 of 34 lessons completed

Go Closures

A closure is a function value that remembers variables from the place where it was made. The closure can read and change those variables after the outer function returns.

A counter factory keeps its own count

makeCounter returns a closure. The closure adds one to count on each call.

package main

import "fmt"

func makeCounter() func() int {
	count := 0
	return func() int {
		count++
		return count
	}
}

func main() {
	next := makeCounter()
	fmt.Println(next())
	fmt.Println(next())
	fmt.Println(next())
}

Two counters stay separate

Each factory call makes a new count. The two counters grow apart from each other.

package main

import "fmt"

func makeCounter() func() int {
	count := 0
	return func() int {
		count++
		return count
	}
}

func main() {
	first := makeCounter()
	second := makeCounter()
	fmt.Println(first())
	fmt.Println(first())
	fmt.Println(second())
}

A closure changes a captured variable

The literal reads and changes total from the enclosing scope. Both calls change the same total.

package main

import "fmt"

func main() {
	total := 10
	addFive := func() {
		total += 5
	}
	addFive()
	addFive()
	fmt.Println(total)
}

Example

package main

import "fmt"

func makeGreeter(name string) func() {
	count := 0
	return func() {
		count++
		fmt.Println("Hello", name, count)
	}
}

func main() {
	greetHana := makeGreeter("Hana")
	greetOmar := makeGreeter("Omar")
	greetHana()
	greetHana()
	greetOmar()
}

Key points

  • A closure keeps access to variables from its enclosing scope.
  • A function literal is function code written without a name.
  • A factory function is a function that builds and returns a closure.
  • Each call to a factory makes fresh variables for the new closure.
  • A closure can change a captured variable.
  • The change stays in place for the next call of the same closure.
  • Two closures from one factory do not share their captured variables.

In this example, makeGreeter builds a closure for Hana and keeps a count for her. The first two calls print her greetings with counts 1 and 2. The Omar closure has its own count, so his first greeting prints 1.

Note

A captured variable stays alive for as long as its closure is in use.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Go Playground

Exercise

Why does a second counter from the same factory start again at 1?