golang 的 defer 语句用于延迟调用。defer 会在当前函数返回之前执行 defer 注册的函数。比如 defer func_defer() 这样语句会让你注册一个函数变量到 defer 的全局链表中,在 defer 语句所在的函数退出之前调用。
defer 可以代替其它语言中 try…catch… 语句,也可以用来处理释放资源等收尾操作,比如关闭文件句柄、关闭数据库连接等。defer 还能用于 panic 的 recovery。
1. defer 的特性
我们先深入的剖析下 defer 具有的特性,知其然也。这些特性是需要我们记住的特点,才能更好的理解 defer 使用的场景。
1) 延迟调用
package main
func main() {
defer println("--- defer ---")
println("--- end ---")
}
运行结果:
--- end ---
--- defer ---
defer 会在 main 函数所有语句之后, return 之前时候调用。核心要点:
延迟调用:defer 语句本身虽然是 main 的第一行,但是 println("— end —") 先打印的;
defer 关键字一定是处于函数上下文:defer 必须放在函数内部;
2) LIFO
一个函数中含有有多个 defer,调用顺序采用压栈式执行,后入先出(LIFO)。
package main
import (
"strconv"
)
func main() {
for i := 1; i <= 3; i++ {
defer println("defer -->" + strconv.Itoa(i))
}
println("--- e