首页后端开发其他后端知识GO中recover错误处理是什么样的

GO中recover错误处理是什么样的

时间2024-03-25 05:06:03发布访客分类其他后端知识浏览272
导读:这篇文章主要为大家详细介绍了GO中recover错误处理是什么样的的内容,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望对大家学习或工作能有帮助,接下来就跟随小编一起来学习吧。...
这篇文章主要为大家详细介绍了GO中recover错误处理是什么样的的内容,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望对大家学习或工作能有帮助,接下来就跟随小编一起来学习吧。

    


Go 的错误处理一直是表现最突出的一块地方,许许多多的同学都提出了各种提案,例如:引入 try-catch、用 panic 代替 if err != nil、引入新的关键字等。但这些都被一一驳回了。

不过社区依然还没放弃,周末看到有一个新的提案《proposal: runtime: add parameters to recover to only return specific types》挺有意思。

语法说明

Go 的 panic、recover、defer 的基本使用方式。如下代码:

package main
import "fmt"
func mayPanic() {

    panic("a problem")
}

func main() {

    defer func() {
    
        if r := recover();
 r != nil {

            fmt.Println("Recovered. Error:\n", r)
        }

    }
()
    mayPanic()
    fmt.Println("After mayPanic()")
}

输出结果:

Recovered. Error:
a problem

新提案

由于有 Go1 兼容性保障,新提案是在原有的 recover 函数上动小手术。希望可以现在运行时的 recover 中加入参数,仅支持返回特定的类型

函数签名:

recover(except ...interface{
}
)

案例代码:

defer func(){
    
    if err := recover(&
    amp;
MyError{
}
    , &
    amp;
HelloError{
}
    );
 err != nil {

        switch e := err.(type) {

        case *MyError:
            fmt.Println(e)
        case *HelloError:
            fmt.Println(e)
        }

    }

}

上面代码中,recover 函数只支持传入 MyError 和 HelloError 的指针类型。再在处理逻辑中根据所传入的错误类型,进行断言分类,实际上去做不同的逻辑处理。

重点就是限定 recover 入参类型。

讨论

有些小伙伴可能发现了,对比看看 PHP 的 try-catch 的用法,与前面的提案代码是不是有好几分神似呢?

如下代码:

try {

    ...
}

catch (Exception $e) {
    
    echo $e->
    getMessage();

}

catch (InvalidArgumentException $e) {
    
    echo $e->
    getMessage();

}

catch (BarException $ex)
{
    
    echo $e->
    getMessage();

}

catch (FooException $ex)
{
    
    echo $e->
    getMessage();

}

本质上这个新的提案是想在不破坏 Go1 兼容性的情况下,在 Go 中实现 try-catch 的方式。

社区在交流时,也发现了用户在现有机制下可以自主实现 Go 的类 try-catch 的模式。

如下代码:

func Recover(expect ...interface{
}
) interface{
}
 {
    
    if err := recover();
 err != nil {

        if len(expect) == 0 {

            return err
        }

        rv1 := reflect.Indirect(reflect.ValueOf(err))
        for _, e := range expect {

            rv2 :=  reflect.Indirect(reflect.ValueOf(e))
            if rv1.Type() == rv2.Type() {

                return err
            }

        }

        panic(err)
    }

    return nil
}
    

这个自制方法的问题是每次 Recover panic 都会将堆栈深度增加 2。因此还是寄希望于 Go 官方能够在运行时支持。

在 Go 标准库的用途对比上,也有产生一定的作用,其涉及到的代码基本为:

总结

这个提案本质上是希望通过在 recover 函数中增加入参控制,再配合内部逻辑实现类似 Go 版本的 try-catch 的错误处理机制模型,且实际在 Go 标准库中有复用的空间。

但现阶段该提案也是赞同和反对参半,也有人认为可以用户自己实现,那就没必要加大复杂度,去做这个收益不够大的实现。

你觉得这能补全 Go 错误处理的一些机制缺陷吗?


以上就是关于“GO中recover错误处理是什么样的”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: GO中recover错误处理是什么样的
本文地址: https://pptw.com/jishu/652558.html
vue中实现图片裁剪的方法是什么 Golang指针如何使用,与指针什么不同

游客 回复需填写必要信息