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.

Related course:
Learn How To Code: Google’s Go (golang) Programming Language

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")