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

如何在延迟函数Go中检测panic(nil)和正常执行?

如何在延迟函数Go中检测panic(nil)和正常执行?

Go
人到中年有点甜 2021-07-02 10:15:45
go 运行时可以检测panic(nil)并报告错误。但是,我无法在红色函数中检测panic(nil)with recover(),defer因为它返回nil,因此我无法将其与正常执行(没有恐慌)区分开来,因为我会测试 的返回值recover()是否为零。例如,defer func(){    var err = recover()    if err != nil {       // Real serious situation. Panic from inner code.       // And we may have some critical resources which        // must be cleaned-up at any cases.       // However, this will not be executed for panic(nil)        rollback()       // I am still not sure that how should I treat `panic`…       // Should I just ignore them?    }}()var err = doTransaction()if err == nil {    commit()    // Happy case.} else {    rollback()  // Regular execution. Just a lucky case.}ROLLBACK 只是一个例子,我想我可以有很多关键情况需要清理。好吧,那些清理代码也不会在真正的程序崩溃时执行,但我想尽可能地进行辩护。无论延迟函数中的参数如何,如何检测任何恐慌?
查看完整描述

2 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

除非我误解了您的问题,否则延迟函数调用在恐慌时运行,即使传递的值为nil以下程序说明了这一点:

package mainimport "fmt"func main() {    defer func() {
        fmt.Println("Recover:", recover())
    }()
    panic(nil)}

因此,您可以panic(nil)通过比较recover()to返回的值来轻松检测是否发生了nil

编辑以回答评论:

是的,这是真的; 延迟调用通常会在函数返回时运行。但是它们也会在 .a 之后展开调用堆栈时运行panic()

问题更新后编辑:

您是正确的,没有办法区分这些情况。另一方面,恐慌nil也没有多大意义——尤其是因为这个限制。

panic(nil)我能想到的唯一用例是故意避免恢复并强制程序因堆栈跟踪而崩溃。不过,还有更优雅的方法可以做到这一点,runtime例如使用包。


查看完整回答
反对 回复 2021-07-05
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

我可以在退出前设置一个标志。


AFAIK,panic 是特定于 goroutine 的,并且单个 goroutine 保证在单线程中。因此,不需要在 variable 周围进行同步/锁定ok。如果我错了,请纠正我。


func clean(ok *bool) {

    if *ok {

        log.Printf("Execution OK. No panic detected.\n")

    } else {

        var reason = recover()

        log.Printf("Some bad thing happen. reason = %v\n", reason)

        panic("Abnormal exit. Program abandoned. Stack-trace here.")

        debug.PrintStack() // Oops. this will not run.

    }

}


func main() {

    var ok bool = false


    defer clean(&ok)

    panic(nil)


    test1() // Here's the main job.


    ok = true

    log.Printf("All work done. Quit gracefully.\n")

}


查看完整回答
反对 回复 2021-07-05
  • 2 回答
  • 0 关注
  • 298 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信