分析Go错误处理优化go recover机制缺陷

 更新时间:2022年07月12日 15:20:01   作者:煎鱼  
这篇文章主要为大家介绍了分析Go错误处理优化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(&MyError{}, &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错误处理优化go recover机制缺陷的详细内容,更多关于go recover错误处理的资料请关注脚本之家其它相关文章!

相关文章

  • Go单元测试利器testify使用示例详解

    Go单元测试利器testify使用示例详解

    这篇文章主要为大家介绍了Go单元测试利器testify使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Go使用database/sql操作数据库的教程指南

    Go使用database/sql操作数据库的教程指南

    Go 语言中,有一个名为database/sql的标准库,提供了统一的编程接口,使开发人员能够以一种通用的方式与各种关系型数据库进行交互,本文就来和大家讲讲它的具体操作吧
    2023-06-06
  • 一文带你了解Go语言中的单元测试

    一文带你了解Go语言中的单元测试

    写过单元测试的开发人员应该理解,单元测试最核心的价值是为了证明:为什么我写的代码是正确的?也就是从逻辑角度帮你检查你的代码。本文就来和大家详细聊聊Go语言中的单元测试,需要的可以参考一下
    2022-07-07
  • Jaeger Client Go入门并实现链路追踪

    Jaeger Client Go入门并实现链路追踪

    这篇文章介绍了Jaeger Client Go入门并实现链路追踪的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • Golang使用pprof和trace进行诊断和修复性能问题

    Golang使用pprof和trace进行诊断和修复性能问题

    在 Go 中,开发人员可以使用强大的内置工具来帮助诊断和修复性能问题,其中两个工具是 pprof 和 trace 包,下面就跟随小编一起来了解下如何使用pprof和trace进行诊断和修复性能问题吧
    2024-01-01
  • golang http 连接超时和传输超时的例子

    golang http 连接超时和传输超时的例子

    今天小编就为大家分享一篇golang http 连接超时和传输超时的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • 基于Golang实现Redis协议解析器

    基于Golang实现Redis协议解析器

    这篇文章主要为大家详细介绍了如何通过GO语言编写简单的Redis协议解析器,文中的示例代码讲解详细,对我们深入了解Go语言有一定的帮助,需要的可以参考一下
    2023-03-03
  • Go实现快速生成固定长度的随机字符串

    Go实现快速生成固定长度的随机字符串

    这篇文章主要为大家详细介绍了怎样在Go中简单快速地生成固定长度的随机字符串,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以学习一下
    2022-10-10
  • 聊聊Go语言编译github上的项目遇到的坑

    聊聊Go语言编译github上的项目遇到的坑

    这篇文章主要介绍了解决Go语言编译github上的项目遇到的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 8个Elasticsearch高频面试题和答案整理

    8个Elasticsearch高频面试题和答案整理

    这篇文章为大家精选了8道Elasticsearch高频面试题和答案,并且给出了这些知识点的应用场景、也给出了解决这些问题的思路,希望对大家有所帮助
    2023-06-06

最新评论