Panicking过程 #
Go 官方文档以手工调用 panic 函数触发 panic 为例,对 panicking 这个过程进行了诠释:当函数 F 调用 panic 函数时,函数 F 的执行将停止。不过,函数 F 中已进行求值的 deferred 函数都会得到正常执行,执行完这些 deferred 函数后,函数 F 才会把控制权返还给其调用者。
对于函数 F 的调用者而言,函数 F 之后的行为就如同调用者调用的函数是 panic 一样,该panicking过程将继续在栈上进行下去,直到当前 Goroutine 中的所有函数都返回为止,然后 Go 程序将崩溃退出。
我们用一个例子来更直观地解释一下 panicking 这个过程:
func foo() {
println("call foo")
bar()
println("exit foo")
}
func bar() {
println("call bar")
panic("panic occurs in bar")
zoo()
println("exit bar")
}
func zoo() {
println("call zoo")
println("exit zoo")
}
func main() {
println("call main")
foo()
println("exit main")
}
上面这个例子中,从 Go 应用入口开始,函数的调用次序依次为main -> foo -> bar -> zoo。在 bar 函数中,我们调用 panic 函数手动触发了 panic。
我们执行这个程序的输出结果是这样的:
call main
call foo
call bar
panic: panic occurs in bar