Go Tutorial · Functions and Methods · Lesson 18 of 30

Go Closures and defer

Anonymous functions, closures, function values and deferred calls.

Functions are values

Functions can be assigned to variables, passed as arguments and returned. An anonymous function that captures variables is a closure:

Example 1
package main

import "fmt"

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

func apply(nums []int, f func(int) int) []int {
	out := make([]int, 0, len(nums))
	for _, n := range nums {
		out = append(out, f(n))
	}
	return out
}

func main() {
	next := counter()
	fmt.Println(next(), next(), next())

	double := func(n int) int { return n * 2 }
	fmt.Println(apply([]int{1, 2, 3}, double))
	fmt.Println(apply([]int{1, 2, 3}, func(n int) int { return n * n }))
}

Output

1 2 3
[2 4 6]
[1 4 9]

Run this on your computer — see “Get Started” for setup.

defer

defer schedules a call to run when the surrounding function returns — perfect for cleanup like closing files or unlocking mutexes. Deferred calls run in last-in, first-out order:

Example 2
package main

import "fmt"

func work() {
	fmt.Println("open resource")
	defer fmt.Println("close resource (deferred 1st, runs last)")
	defer fmt.Println("flush buffer (deferred 2nd, runs first)")
	fmt.Println("doing work")
}

func main() {
	work()
}

Output

open resource
doing work
flush buffer (deferred 2nd, runs first)
close resource (deferred 1st, runs last)

Run this on your computer — see “Get Started” for setup.

Test yourself

In what order do multiple deferred calls run?

  1. First in, first out
  2. Last in, first out
  3. Random
  4. Alphabetical
Show answer

Answer: Last in, first out