总结:
- 如果没有recover(), panic打印错误信息之前会,执行已经注册的defer,执行顺序是跟注册顺序相反,直到main函数的defer执行完之后,才会打印错误信息。
- 如果有recover(),并且注册recover()的defer在panic之前,panic会从根据注册defer的栈中依次从栈顶到栈底执行defer,如果有recover(),那么该panic会被捕获。
- 注意:recover() 函数必须被defer注册的延迟函数直接调用
defer func() {err := recover() fmt.Println(err, "recover")}()
而不是直接defer recover(),而且不能间接调用。 - defer 被执行就意味着当前函数要退出,即使当函数还没有执行完也不能执行了,而退回到调用该函数的函数中,外部函数依然能够继续执行。
package main
import "fmt"
func main() {
defer fmt.Println("main defer")
foo2()
fmt.Println("main over")
}
func foo2() {
defer func() {
err := recover()
fmt.Println(err, "recover")
}()
defer fmt.Println("foo2 defer")
fmt.Println("foo3 start ")
foo3()
}
func foo3() {
foo()
}
func foo() {
panic("ooo")
}
//foo3 start
//foo2 defer
//ooo recover
//main over
//main defer