Golang: Language: Defer

 19th December 2020 at 11:05pm

defer 语句,会在函数返回后执行:

func main() {
    defer fmt.Println("World")
    fmt.Println("Hello")
}
Hello
World

defer 的可以是函数、也可以是实例的方法。

defer 时函数或方法的参数,是在 defer 语句当时求值(evaluate)的:

package main

import (  
    "fmt"
)

func printA(a int) {  
    fmt.Println("value of a in deferred function", a)
}
func main() {  
    a := 5
    defer printA(a)
    a = 10
    fmt.Println("value of a before deferred function call", a)
}
value of a before deferred function call 10  
value of a in deferred function 5 

同个函数里,先 defer 的语句后执行。

defer 的关键用法

go 中一个常见的 pattern 是出错时函数马上返回 (nil, err)defer 一般用于资源释放,使得这种情况下也可以释放资源,而不需要在每个 return 前手动释放资源:

func getUserById(id int) {
    var name string
    rows, err := db.Query("select id, name from users where id = ?", 1)
    if err != nil {
        return err
    }
    defer rows.Close()
    
    err = rows.Err()
    if err != nil {
        return err
    }
    
    for rows.Next() {
        err := rows.Scan(&id, &name)
        if err != nil {
            return err
        }
        log.Println(id, name)
    }
}