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

 更新时间:2022年12月07日 16:22:46   作者:bluesGavin  
这篇文章主要为大家介绍了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类型的资料请关注脚本之家其它相关文章!

相关文章

  • golang 开启opencv图形化编程

    golang 开启opencv图形化编程

    这篇文章主要为大家介绍了golang 开启opencv图形化编程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Golang交叉编译(跨平台编译)的使用

    Golang交叉编译(跨平台编译)的使用

    本文主要介绍了Golang交叉编译(跨平台编译)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Go语言安装和GoLand2021最全超详细安装教程

    Go语言安装和GoLand2021最全超详细安装教程

    Go语言和GoLand的关系好比于java和idea、python和pycharm,因此我们需要先安装好Go语言后才能安装GoLand。它的安装和java,python的安装大同小异,好了,下面给大家带来了GoLand2021安装教程,需要的朋友参考下吧
    2021-08-08
  • Go并发与锁的两种方式该如何提效详解

    Go并发与锁的两种方式该如何提效详解

    如果没有锁,在我们的项目中,可能会存在多个goroutine同时操作一个资源(临界区),这种情况会发生竞态问题(数据竞态),下面这篇文章主要给大家介绍了关于Go并发与锁的两种方式该如何提效的相关资料,需要的朋友可以参考下
    2022-12-12
  • Go语言学习之时间函数使用详解

    Go语言学习之时间函数使用详解

    这篇文章主要为大家详细介绍了Go语言中时间函数的使用方法,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可以参考一下
    2022-04-04
  • Go语言标准错误error全面解析

    Go语言标准错误error全面解析

    Go语言中的错误处理是通过内置的error接口来实现的,其中errorString和wrapError是两种常见的错误类型实现方式,errorString通过errors.New()方法实现,而wrapError则通过fmt.Errorf()方法实现,支持错误的嵌套和解析
    2024-10-10
  • golang 生成二维码海报的实现代码

    golang 生成二维码海报的实现代码

    这篇文章主要介绍了golang 生成二维码海报的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • golang中的net/rpc包使用概述(小结)

    golang中的net/rpc包使用概述(小结)

    本篇文章主要介绍了golang中的net/rpc包使用概述(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 详解Golang中Channel的高级用法

    详解Golang中Channel的高级用法

    在Go语言中,chan(通道)是一种用于在不同的goroutine之间进行通信的机制,通道可以是无缓冲的(同步的)或有缓冲的(异步的),本文给大家详细介绍了Golang中Channel的高级用法,需要的朋友可以参考下
    2024-05-05
  • Go语言如何利用Mutex保障数据读写正确

    Go语言如何利用Mutex保障数据读写正确

    这篇文章主要介绍了互斥锁的实现机制,以及 Go 标准库的互斥锁 Mutex 的基本使用方法,文中的示例代码讲解详细,需要的小伙伴可以参考一下
    2023-05-05

最新评论