defer


The defer statement is used to postpone a function call executed immediately before the surrounding function returns. The common uses of defer include releasing resources (i.e., unlock the mutex, close file handle.), do some tracing(i.e., record the running time of function), etc. E.g., an ordinary accessing global variable exclusively is like this:

  1. var mu sync.Mutex
  2. var m = make(map[string]int)
  3. func lookup(key string) int {
  4. mu.Lock()
  5. v := m[key]
  6. mu.Unlock()
  7. return v
  8. }

An equivalent but concise format using defer is as follow:

  1. var mu sync.Mutex
  2. var m = make(map[string]int)
  3. func lookup(key string) int {
  4. mu.Lock()
  5. defer mu.Unlock()
  6. return m[key]
  7. }

You can see this style is more simpler and easier to comprehend.

The defer statements are executed in Last-In-First-Out sequence, which means the functions in latter defer statements run before their previous buddies. Check the following example:

  1. package main
  2. import "fmt"
  3. func main() {
  4. defer fmt.Println("First")
  5. defer fmt.Println("Last")
  6. }

The running result is here:

  1. Last
  2. First

Although the function in defer statement runs very late, the parameters of the function are evaluated when the defer statement is executed.

  1. package main
  2. import "fmt"
  3. func main() {
  4. i := 10
  5. defer fmt.Println(i)
  6. i = 100
  7. }

The running result is here:

  1. 10

Besides, if the deferred function is a function literal, it can also modify the return value:

  1. package main
  2. import "fmt"
  3. func modify() (result int) {
  4. defer func(){result = 1000}()
  5. return 100
  6. }
  7. func main() {
  8. fmt.Println(modify())
  9. }

The value printed is 1000, not 100.

References:
The Go Programming Language;
Defer, Panic, and Recover.