๐ŸŽ“ A1Learner
๐Ÿ”
0 of 34 lessons completed

Go Defer in Depth

Defer in depth is the set of rules that fix when a deferred call runs and what values it sees. A deferred call runs when its enclosing function returns.

Deferred arguments are read at defer time

The defer line reads n while it is still 10. The later change to 99 does not reach the deferred call.

package main

import "fmt"

func main() {
	n := 10
	defer fmt.Println(n)
	n = 99
	fmt.Println(n)
}

Three defers run last-in first-out

Three calls are deferred in order. They run in the reverse order at the end.

package main

import "fmt"

func main() {
	defer fmt.Println("first deferred")
	defer fmt.Println("second deferred")
	defer fmt.Println("third deferred")
	fmt.Println("main work")
}

A deferred closure changes a named return value

price names its result total. The deferred literal adds 25 to total before the caller reads it.

package main

import "fmt"

func price() (total int) {
	total = 100
	defer func() {
		total += 25
	}()
	return total
}

func main() {
	fmt.Println(price())
}

Example

package main

import "fmt"

func report() {
	fmt.Println("start")
	defer fmt.Println("end")
	fmt.Println("work one")
	fmt.Println("work two")
}

func main() {
	report()
	fmt.Println("done")
}

Key points

  • The arguments of a deferred call are read when the defer line runs.
  • Deferred calls run in last-in first-out order.
  • Last-in first-out means the last deferred call runs first.
  • A deferred function literal runs at return time.
  • A deferred literal reads the current values of the variables it captures.
  • A named result is a result declared with a name in the function signature.
  • A deferred literal can change a named result before the caller sees it.

In this example, report prints start first. The defer line sets the end print aside. The two work lines print next. The deferred end line prints when report returns. Main then prints done.

Note

Deferred calls still run when a function returns early with an error.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Go Playground

Exercise

A function defers print A, then print B, then print C. Which deferred line prints first?