根据我的理解,当恐慌恢复时,我期望程序退出并表现出正常行为,但事实并非如此。我期望最后一行打印“程序结束”是正确的吗?
如果出现运行时错误,它不会被打印,是吗?
package main
import (
"fmt"
)
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Cause of panic ==>>, %q\n", r)
}
}()
f(3)
fmt.Println("End of program")
}
func f(x int) {
fmt.Printf("f(%d) is called.\n", x) //panic triggered when x==0
// defer called in reverse order in case of panic
defer fmt.Printf("defer %d\n", x+0/x)
f(x-1)
}
Go 规范对发生的情况有很好的描述恐慌/恢复 https://golang.org/ref/spec#Handling_panics。恐慌会终止当前函数和所有调用者,直到程序退出。在途中,它执行所有延迟函数。如果这些函数之一具有recover()
并干净地退出,恐慌传播就会停止。
在您的情况下,恐慌会按以下顺序终止函数:f(0)
, f(1)
, f(2)
, f(3)
, main()
,运行每个函数的延迟函数。
你的延迟函数recover()
位于main()
。这意味着main()
在到达 print 语句之前被恐慌中断,并在之后调用 deferred 函数.
如果您想捕获恐慌、恢复并在 main 中继续,则需要添加一个中间函数。例如:
func main() {
handlePanic(3)
fmt.Println("End of program")
}
func handlePanic(x int) {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Cause of panic ==>>, %q\n", r)
}
}()
f(x)
}
func f(x int) {
fmt.Printf("f(%d) is called.\n", x) //panic triggered when x==0
// defer called in reverse order in case of panic
defer fmt.Printf("defer %d\n", x+0/x)
f(x-1)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)