首页  >  文章  >  后端开发  >  Golang 延迟函数可以在不终止恐慌序列的情况下触发新的恐慌吗?

Golang 延迟函数可以在不终止恐慌序列的情况下触发新的恐慌吗?

Barbara Streisand
Barbara Streisand原创
2024-11-03 07:08:29365浏览

Can Golang Defer Functions Trigger New Panics Without Terminating the Panic Sequence?

延迟函数内部的恐慌是否可以接受,特别是在现有恐慌期间?

考虑以下代码片段:

func sub(){
    defer func (){
        panic(2)
    }()
    panic(1)
}

func main(){
    defer func(){
        x:=recover()
        println(x.(int));
    }()
    sub()
}

执行此命令时代码中,似乎最初的panic(1)被第二个panic(2)取代。

是否允许以这种方式继续,或者调用可能在defer 函数?

是的,这是可以接受的。 由 defer 函数引起的恐慌并不是一个新的或独特的情况;它只是表明恐慌序列将继续。

提供的示例代码演示了这种可接受性,并说明了即使从 defer 函数调用的panic() 也可以通过对recover() 的“更高”级别调用来捕获.

Golang 规范规定,如果在执行延迟函数期间发生恐慌,如果恢复函数在没有捕获它的情况下执行了恐慌(),恐慌序列将不会结束。

此外,即使在延迟函数中调用panic(),所有其他延迟函数也会被执行。然而,延迟函数中没有恢复函数的panic()将“包装”现有的panic,而不是“覆盖”它。

例如,考虑以下代码:

func main() {
    defer func() {
        fmt.Println("Checkpoint 1")
        panic(1)
    }()
    defer func() {
        fmt.Println("Checkpoint 2")
        panic(2)
    }()
    panic(999)
}

输出:

Checkpoint 2
Checkpoint 1
panic: 999
    panic: 2
    panic: 1

即使每个 defer 函数都调用panic(),它们仍然会被执行,并且生成的panic序列显示传递给每个panic()调用的值。

当在延迟函数中调用recover()时,最终的打印输出还会显示此“恢复”信息:

defer func() {
    recover()
    fmt.Println("Checkpoint 1")
    panic(1)
}()
defer func() {
    recover()
    fmt.Println("Checkpoint 2")
    panic(2)
}()

输出:

Checkpoint 2
Checkpoint 1
panic: 999 [recovered]
    panic: 2 [recovered]
    panic: 1

以上是Golang 延迟函数可以在不终止恐慌序列的情况下触发新的恐慌吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn