登录
首页 >  Golang >  Go问答

defer 函数内部是否允许恐慌发生,尤其是在已经发生恐慌时?

来源:stackoverflow

时间:2024-02-09 14:42:24 259浏览 收藏

从现在开始,努力学习吧!本文《defer 函数内部是否允许恐慌发生,尤其是在已经发生恐慌时?》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

问题内容

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

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

我尝试了这段代码,似乎第一个恐慌 panic(1) 被第二个恐慌 panic(2) “覆盖”。

但是这样做可以吗?或者调用可能会在 defer 函数内发生恐慌的 Golang 函数?

(在 C++ 中,从析构函数中抛出异常几乎是不可接受的。如果堆栈已经展开,它会终止程序。我想知道以类似方式发生恐慌在 Golang 中是否会很糟糕。)


正确答案


是的,没关系。延迟函数引起的恐慌并不是真正的新的特殊状态,它只是意味着恐慌序列不会停止。

您的示例代码也证明了它没问题,甚至 panic() 称为可以通过对 recover() 的“上”级调用来停止延迟函数。

规范:处理恐慌:

这里需要注意的一件事是,即使您在延迟函数中调用 panic(),所有其他延迟函数仍然会运行。另外,来自延迟函数的没有 recover()panic() 宁愿“包装”现有的恐慌,而不是“覆盖”它(尽管 recover() 调用确实只会返回传递给最后一次 panic() 调用)。

请参阅此示例:

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

输出(在 Go Playground 上尝试一下):

c2e572c1c34a0369ef7​​989373914f540

即使所有延迟函数都调用 panic(),所有延迟函数都会执行,并且打印的最终恐慌序列包含传递给所有 panic() 调用的值。

如果您在延迟函数中调用 recover(),您还会在最终打印输出中获得此“已恢复”状态或信息:

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

输出(在 Go Playground 上尝试一下):

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

到这里,我们也就讲完了《defer 函数内部是否允许恐慌发生,尤其是在已经发生恐慌时?》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>