为了账号安全,请及时绑定邮箱和手机立即绑定

从恐慌中恢复的程序未按预期退出

从恐慌中恢复的程序未按预期退出

Go
蝴蝶不菲 2022-06-27 16:57:17
据我了解,当恐慌恢复时,我希望程序退出并表现出正常行为,但事实并非如此。我期望最后一行打印“程序结束”是否正确?如果出现运行时错误,它不会被打印,是吗?package mainimport (    "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)}
查看完整描述

2 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

Go 规范很好地描述了panic/recover发生的事情。恐慌会终止当前函数和所有调用者,直到程序退出。在途中,它执行所有的延迟函数。如果其中一个函数有 arecover()并且干净地退出,则停止恐慌传播。


在您的情况下,恐慌按以下顺序终止函数:f(0), f(1), f(2), f(3), main(), 运行每个函数的延迟函数。


您的延迟函数recover()位于main(). 这意味着main()在到达 print 语句之前被恐慌中断,并且延迟函数在之后被调用。


如果你想在 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)

}


查看完整回答
反对 回复 2022-06-27
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

不会打印“程序结束”。

当检测到恐慌时,导致恐慌的函数立即返回,以及调用该函数的函数等,一直到调用的函数recover。当该函数返回并恢复时,程序会继续运行,就好像没有发生恐慌一样。

在您的情况下,main是恢复的功能。恐慌在f(3)调用时触发,并且在 main 返回后进行恢复,绕过 println。


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 176 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号