登录
首页 >  Golang >  Go问答

在恢复恐慌后继续执行,而无需确定可能触发恐慌的函数是哪个

来源:stackoverflow

时间:2024-02-10 16:09:25 166浏览 收藏

本篇文章给大家分享《在恢复恐慌后继续执行,而无需确定可能触发恐慌的函数是哪个》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

问题内容

我被提到了这个问题:从恐慌中恢复的程序没有按预期退出 它工作正常,但它依赖于知道恐慌发生的位置才能放置延迟函数。 我的代码如下。

package main

import "fmt"

func main() {
    defer recoverpanic()
    f1()
    f2()
    f3()
}

func f1() {
    fmt.println("f1")
}

func f2() {
    defer f3() //<--- don't want to defer f3 here because i might not know f2 will panic, panic could occuer elsewhere
    fmt.println("f2")
    panic("f2")
}

func f3() {
    fmt.println("f3")
}

func recoverpanic() {
    if r := recover(); r != nil {
        fmt.printf("cause of panic ==>> %q\n", r)
    }
}

在恐慌函数中让延迟函数调用 f3() 有效,输出如下。

f1
f2
f3
cause of panic ==>> "f2"

如果您的应用程序不知道在哪里发生恐慌,我是否需要在每个可能发生恐慌的函数中延迟呢? 注释掉 defer f3() 给出以下输出。

f1
f2
Cause of panic ==>> "f2"

f3 永远不会运行。

我的问题是如何继续执行程序而不在每个可能恐慌的函数中进行延迟函数调用?


正确答案


恐慌后无法恢复函数执行。当当前执行行无法正确继续时,会使用 panic。在恐慌之后(如果可能的话)任意恢复执行会立即引发另一次恐慌,因为状态已经不正确,仅仅向前推进并不能解决这个问题。

例如,假设一个函数在尝试读取切片越界时发生恐慌。怎么能继续下去呢?继续下去意味着什么?它应该只读取越界内存位置并获取垃圾数据吗?继续使用零值吗?从切片中获取不同的值?

您必须处理错误情况;通过显式恢复,或者先发制人地检查/纠正会导致恐慌的情况。至少在标准库中,可能引发恐慌的函数会在其文档中如此说明,并解释哪些条件会导致恐慌。

如果您通常需要安全地调用 void 函数并从任何恐慌中恢复,您可以为此创建一个简单的包装函数。

func try(f func()) {
    defer func() {
        if err := recover(); err != nil {
            fmt.println("caught panic:", err)
        }
    }()
    f()
}

然后

func main() {
    try(f1)
    try(f2)
    try(f3)
}

以上就是《在恢复恐慌后继续执行,而无需确定可能触发恐慌的函数是哪个》的详细内容,更多关于的资料请关注golang学习网公众号!

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