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