go defer语句使用
1. 定义
defer
语句能够延迟执行某个函数(deferred function),直到使用defer
语句的函数返回前。例如:
package main
import "fmt"
func power(i int) int {
fmt.Printf("\n i is %d and result is %d ", i, i*i)
return i * i
}
func main() {
i := 0
for ; i < 5; i++ {
defer power(i)
}
i += 5
power(i)
}
从上面执行的结果可以得出几个结论:
最后一个
power
函数执行完成后,main
函数返回前,开始执行for
循环里的 deferred function 。deferred function 的参数是在执行
defer
语句时计算的,不是在调用 deferred function 时计算的(执行defer
语句时i
为0,1,2,3,4
,调用 deferred function 时i
为10)。多个 deferred function 执行时遵守 LIFO (后进先出)原则。
下面例子更清晰的说明 deferred function 的参数是在执行defer
语句的时候计算的。
package main
import "fmt"
func trace(s string) string {
fmt.Println("entering:", s)
return s
}
func un(s string) {
fmt.Println("leaving:", s)
}
func a() {
defer un(trace("a"))
fmt.Println("in a")
}
func b() {
defer un(trace("b"))
fmt.Println("in b")
a()
}
func main() {
b()
}
defer
能够保证函数执行完之前调用 deferred function(例如关闭文件),防止执行分支过多之后出现遗漏。但同时执行的流程发生了变化(例如关闭文件在函数开始的地方),对可读性造成了一定的影响。
2. panic defer recover
defer
关键字主要的使用场景是异常恢复,panic defer recover
模式参考异常处理。