我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Go语音开发中常见Error类型处理示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Go语音开发中常见Error类型处理示例详解

前言

上文我们了解了 Error 在 Go 中的设计理念。单从理念上来看, Error 的设计似乎有利于逻辑处理。但实际上,在开发过程中,我们还会遇到各种各样的困难。为了优化开发的流程,开发者们发明了很多处理 Error 的做法。今天我们就来看看目前 Go 开发中常见的几大 Error 类型。

透明错误处理策略

在最简单的 Go Error 设计中,开发者被期望通过判定函数返回的 err 值来确定调用是否正常。

value, err := doSomething()
if err != nil {
	// 错误处理
}
// 逻辑操作

这是 Go 语言中最常见的错误处理策略 ,80%以上的 Go 错误处理情形都可以归类到这种策略下。这样构造出的错误值代表的上下文信息,对错误处理方是透明的,因此这种策略称为 透明错误处理策略

这种策略最大的问题是,无法判定错误的原因和种类。它只是简单地把”是否出错“分为了两路逻辑。一旦我们的业务要求我们针对不同的错误原因,做不同的处理,这种情况就行不通了。

带来的问题

透明策略只解决了”是否出错“的问题,但开发者无法知道错误的原因。如果想要得到错误的内容,需要主动解析error值,这也引出了下面要讲的处理策略。

哨兵(Sentinel)错误处理策略

哨兵策略策略主要是解决透明错误处理策略精度不够的情况,它可以让开发者得到“是什么错误”,而不仅是”是否出错“。实际上,它就是通过预定义错误类型,在错误处理时,判断错误是否属于预定义的类别,从而做出处理。

因此我们可以得到它最简单的实现:

value, err := doSomething()
if err!=nil { 
    // 通过err.Error()获得错误信息
    switch err.Error(){ 
        case "bufio: negative count": 
        	//特点错误处理 
        	return 
        // 其他判断
        default: 
        	// 未知错误原因
        	return 
    } 
}

但这显然不是好的写法,会导致很严重的耦合问题。Go 1.13 之后,我们可以用 error.Is 方法很好地解决这个问题。

// 定义错误类型,一般变量用Err开头
var(
  ErrInvalidUnreadByte=errors.New("bufio: invalid use of UnreadByte")ErrInvalidUnreadRune=errors.New("bufio: invalid use of UnreadRune")
  ErrBufferFull=errors.New("bufio: buffer full")
  ErrNegativeCount=errors.New("bufio: negative count")
)

func main(){
	value, err := doSomething()
  	if errors.Is(err,ErrBufferFull){
    	//判断是否为某类型错误
  	}
}

带来的问题

虽然哨兵策略解决了我们不能获得错误原因的问题,但它本身也存在着设计缺陷。

1.对errors.Error()的依赖

== 的判断依赖着 errors.Error() 的输出。这是哨兵策略最大的问题。他导致了 error 值的扩展性很差,假如开发者想要为 error 带上上下文或者错误行号,文件位置等信息,都会破坏哨兵策略的判断。

从某种角度来看,errors.Error() 的输出更应该是用于开发者的调试使用,而不应该作为程序判断机制的一部分。

2.定义的错误类型会被公开

很多时候为了做错误类型判断,一些包内需要定义许多错误类型。而这些错误类型通常会被共用,这使得他们不得不被公开。在公共库中,被公开的错误类型必须有专门的文档说明,否则会对使用者造成困惑。这会额外增加开发者的工作量。

再者,有时为了判断某个特殊错误类型,使用者会引入对应的包。假如这种情况大量存在,会导致整个库生态极其混乱。

Error types

Error types 是实现了 errors 接口的自定义类型,目的是为了更加具体地描述错误。开发者可以在类型上带上需要的信息,如行号,文件位置等。可以参考下方:

type MyError struct {
    Msg string	// 错误信息
    Line int	// 行号
    FIle string // 文件位置
}

// 实现 errors 接口
func (e *MyError) Error()string{
    return fmt.Sprintf("%s:%d: %s",e.File,e.Line,e.Msg)
}
    

上面提到,修改 error 值会导致哨兵策略的失效, Error types 就是例子之一。由于是自定义的类型,我们不能再用 == 判断错误类型了,而是改用断言。

value, ok := x.(MyError)
if ok {
    //判断是否为某类型错误
}

带来的问题

可以看到 Error Types 最大的优势是其丰富的错误描述能力。但它仍然没有解决哨兵策略下的问题。

不透明错误处理策略(Opaque errors)

不透明错误处理策略可以说是最灵活的处理方式,它要求代码与调用者之间的耦合最少。开发者可以知道”是否出错“,但无法得到错误的内部信息。

value, err := doSomething()
if err != nil {
	// 错误处理
}
// 逻辑操作

是的,在使用上不透明策略透明策略是很相似的。其中最大的不同是,透明策略可以通过 error.Error() 接口获得错误信息。而不透明策略中是不可以的。

那如果开发者需要判断错误类型怎么办呢?不透明策略更推荐的是断言 error 实现的行为,而不是特定的类型或值。可以参考下方代码:

type temporary interface {
    Temporary() bool
}
// 封装判断函数
func IsTemporary(err error) bool {
    // 断言
    te, ok := err.(temporay)
    // 是否满足条件
    return ok && te.Temporary()
}

带来的问题

不透明策略跟透明策略一样,是很灵活的策略。他们的区别只在于错误的信息是否开放。因此,不透明策略依旧存在信息量缺乏的问题。

总结

今天我们了解了目前 Go 开发中常见的四种 Error 类型。这些类型各有优劣,需要开发者在实际开发者中深入思考,做出取舍。通常我们需要考虑,我们开发的是工具还是业务,我们需要错误为我们提供灵活度还是精确的信息。掌握本文的内容,可以让你在遇到错误处理时,有更多的处理思路。

当然,每种方式又会有问题,在接下来的文章里,我会分享一些常见的错误处理操作。

以上就是Go语音开发中常见Error类型处理示例详解的详细内容,更多关于Go语音Error类型的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Go语音开发中常见Error类型处理示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go语音开发中常见Error类型处理示例详解

这篇文章主要为大家介绍了Go语音开发中常见Error类型处理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录