The Go language’s defer statement delays processing of the statements that follow it. When the function that defer is about to return, the deferred statements are executed in reverse order of defer. Similar to stack access, first in last out. The statement that is deferred first is executed, and the statement that is deferred last is executed.

The use of Go’s defer is very similar to finally in Java. They are used to release resources, such as file handles, database connections, or mutex locks.

Defer features

  1. The keyword defer is used to register deferred calls
  2. These calls are not executed until return. Therefore, it can be used for resource cleaning
  3. Multiple defer statements, executed on a first-in, last-out basis
  4. The variables in the defer statement were determined when the defer declaration was made

Defer purposes

  1. Close the file handle
  2. Lock resource release
  3. Database connection release

The execution order of multiple delayed statements

As we’ve seen above, defer registers the delay handler in a very similar way to stack access. Adhering to the first out of the execution order. Verify this with the following procedure.

package main

import "fmt"

func main (a) {
    fmt.Print("defer begin ")

    defer fmt.Print("1")
    defer fmt.Print("2")
    defer fmt.Print("3")

    fmt.Print(" defer end ")}Copy the code
  • Defer begin defer end 3 2 1

As you can see from the program output, the statements following defer are executed after the normal statements have been executed. And it was executed in reverse order of defer.

Defer releases resources

Use the previous example as a demonstration. The closing of the file is deferred at code 1. The file resource is released when the function is ready to return.

package main

import "fmt"
import "os"

func main (a) {
    f, err := os.Open("D:\\tmp\\hello.txt")

    iferr ! =nil {
        fmt.Printf("Error opening file, %v", err)
        return
    }
    defer f.Close() / / 1

    buf := make([]byte.8)
    forn, _ := f.Read(buf); n ! =0; n, _ = f.Read(buf) {
        fmt.Printf("Read %d byte contents, contents: %q\n", n, buf[:n])
    }
}
Copy the code

The defer anonymous function

While the previous examples deferred processing a function, defer can defer processing anonymous functions as well, as illustrated below.

package main

import "fmt"

func main (a) {
    fmt.Print("defer begin ")

    defer func (a) {
        fmt.Print("1")
        fmt.Print("2")
        fmt.Print("3")
    }()

    fmt.Print(" defer end ")}Copy the code
  • Defer begin defer end 1 2 3