我是靠谱客的博主 无语烤鸡,最近开发中收集的这篇文章主要介绍Go error的使用方式详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

概述

当我们需要在Go项目中设计error,就不得不先知道Go error几种常用方法。标准库是一个非常好的学习方式,除此之外Go1.13的errors特性也需要掌握。

error使用方式

1.直接判等

这里的判等又分为变量判等和类型判等。
适用于pkg中预先定义好了多个error变量或类型,err只可能是这些变量的其中一个。
案例:os.IsExist(err)

// 变量判等
var errObj = errors.New(errObj)
func IsErrObj(err error) bool {
    return err == errObj
}
// 类型判等
type PathError struct {
   Op   string
   Path string
   Err  error
}
func IsPathError(err error) bool {
    switch e := err.(type) {
    case *PathError:
        return true
    default:
        return false
    }
} 

2.组合error接口,构建更强大的error接口

适用于构造pkg级别专用的error接口类型,同时在struct中组合Err变量表示底层错误
案例:net.Error interface

package net
type Error interface {
   error
   Timeout() bool   // Is the error a timeout?
   Temporary() bool // Is the error temporary?
}

type AddrError struct {
   Err  string
   Addr string
}

3.Errno模式

我们知道Linux有大量的错误码,表示了各种错误类型,对于很多系统而言错误码非常好用。Go如何兼容这种errono模式呢?
案例:sysacall.Errno

type Errno uintptr
func (e Errno) Error() string {
   if 0 <= int(e) && int(e) < len(errors) {
      s := errors[e]
      if s != "" {
         return s
      }
   }
   return "errno " + itoa.Itoa(int(e))
}

4.Go1.13的Wrap模式

在一些场景下,error是有链式关系的,我们固然可以自己实现一种链式error类型,但是Go1.13引入了语言级别的支持。它非常简单,只要3个重要的用法:

// 创建error
err2 := fmt.Errorf("%w", err1)
// 判断error链条中是否包含某个err变量
ok := errors.Is(err2, err1) // true
// 判断error链条中是否可赋值为某个err类型,成功则赋值给target
type Errno int
func (e *Errno) Error() string {
   return strconv.Itoa(int(*e))
}

func test() {
    var no = Errno(1)
    no1 := fmt.Errorf("%w", &no)
    no2 := fmt.Errorf("%w", no1)
    
    var target *Errno
    ok := errors.As(no2, target)
    fmt.Println(ok, target) // true, 1
}

以上代码都依赖 errors.Unwrap 函数,这个函数通过反射解析出链式error的上一个error。
从代码可以看出,error.Is 用于我们有2个err变量的情况下,判断前者是否链接了后者;
error.As 用于我们有一个err变量和一种error类型,想要判断链子中是否包含了这种error类型,如果是,我们顺带将值保存在target中,相当于丢弃了一些链式的信息,返璞归真。 这里有2个注意点:

  • Unwrap依赖反射,我们知道Go的反射是很慢的,所以需要考虑性能的场景慎用
  • As函数使用是,target本身必须是struct的指针类型,并且要取地址,否则可能会panic

5. Go版本低时的链式error

有时候我们会看到 github.com/pkg/errors 这个包,它其实就是老版本Go想要使用链式error所引用的包,它常用的方法是 Wrap 和 Cause,所以看到这2个函数就可以猜到一个项目没有使用新的errors特性。

到此这篇关于Go error的使用方式选择的文章就介绍到这了,更多相关Go error使用内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!

最后

以上就是无语烤鸡为你收集整理的Go error的使用方式详解的全部内容,希望文章能够帮你解决Go error的使用方式详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(92)

评论列表共有 0 条评论

立即
投稿
返回
顶部