错误类型处理在go中是非常重要的,但是代码不多,本文将分析源码内容。
errors.go
error是一个内建的类型,实现了error接口
1 | type error interface { |
errors包下通过New创建一个error对象,事实上返回的就是一个实现了error接口类型的结构体,其中Error()返回了该错误信息的内容。
1 | // New returns an error that formats as the given text. |
warp.go
在warp文件下,有三个方法,分别为Unwrap(err error) error
,Is(err, target error) bool
,As(err error, target interface{}) bool
,都是在1.13新加入的方法。
Unwrap(err error) error
使用该方法,需要传入的error
类型实现Unwrap() error
- 通过判断是否实现了
Unwrap() error
- 是,调用Unwrap()方法,返回err
- 否,返回nil
1 | // Unwrap returns the result of calling the Unwrap method on err, if err's |
Is(err, target error) bool
判断该错误类型是否和目标类型是一致类型
- 如果目标类型为nil,则判断被比较类型是否也是nil
- 通过一个for循环不断判断
- 如果目标类型能被比较并且被比较类型和目标类型值相等就返回true
- 如果被比较类型实现了
Is(error) bool
接口,则调用接口方法,判断是否是相等的 - 解包被比较类型,继续下一轮循环,或者解包到最里层都没有寻找到被比较类型与目标类型可匹配
1 | // Is reports whether any error in err's chain matches target. |
As(err error, target interface{}) bool
As方法应将目标设置为其值,如果err匹配目标指向的类型,则返回true。
- 如果目标类型为nil,或者不是指针类型,或者该类型没有实现error接口,则panic
- 通过一个for循环不断判断
- 如果被比较类型能被目标类型赋值,就进行赋值,返回true
- 如果被比较类型实现了
As(interface{}) bool
接口,则调用接口方法,进行赋值,并返回true - 解包被比较类型,继续下一轮循环,或者解包到最里层都没有寻找到实现的As方法都没有赋值成功
1 | // As finds the first error in err's chain that matches the type to which target |