Defer is a special statement in Go. The defer statement schedules a function to be called after the current function has completed.

Go will run all statements in the function, then do the function call specified by defer after.

Download PDF

Example

Defer

The normal execution in a Go function is top to bottom, if you had the function below, it would first call who() (top) and then hello (bottom).

1
2
3
4
func main() {
who()
hello()
}

If you add the defer statement, it will remember to call it after the function is finished.

1
2
3
4
func main() {
defer who()
hello()
}

It will first call hello() and then who().

Demo

The example below uses the defer statement to change the execution order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"

func hello() {
fmt.Println("Hello")
}

func who() {
fmt.Println("Go")
}

func main() {
defer who()
hello()
}

Defer can also be called on simple function calls from packages, like this:

1
2
3
4
func main() {
defer fmt.Println("Hello")
fmt.Println("World")
}

Practical example

If you want to create and write a file, the steps would normally be:

  1. create file
  2. write file
  3. close file

With the defer statement you could write:

  1. create file
  2. (defer) close file after function completes
  3. write file

In code that looks like this:

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"
import "os"

func main() {
f, _ := os.Create("hello.txt")
defer f.Close()
fmt.Fprintln(f,"hello world")
}

This has some advantages:

  • readability
  • if run-time panic occurs, deferred functions are still run
  • if the function has return statements, close will happen before that

Exercise

  1. Predict what this code does:
1
2
3
defer fmt.Println("Hello")
defer fmt.Println("!")
fmt.Println("World")