文章目录
- 前言
- 一、概述
- 二、源码理解
- 包
- 函数
- New
- Unwrap
- Is
- As
- Join
- 结构
- errorString
- errorString方法
- Error
- joinError
- joinError方法
- Error
- Unwrap
- 变量
- ErrUnsupported
- errorType
- 总结
前言
本文章帮助大家对errors包的理解。
一、概述
errors是Go语言内置的标准库之一,用于处理和表示错误。
二、源码理解
包
package errors
import "errors"
使用errors时,需引入此包。
函数
New
func New(text string) error {return &errorString{text}
}
创建并返回一个错误内容为text的错误error(errorString)。
Unwrap
func Unwrap(err error) error {u, ok := err.(interface {Unwrap() error})if !ok {return nil}return u.Unwrap()
}
返回err的拆包结果(error)。若err没有Unwrap() error方法,返回空。
Is
func Is(err, target error) bool { /*...*/ }
若err错误树中包含匹配target错误的错误,则返回true。
重点:错误树包含错误本身,然后通过Unwrap方法重复地拆包出错误,为深度优先的先序遍历。匹配是指相等或者实现了Is(error) bool方法且Is(target)返回true。
注意:这里Unwrap方法可能返回error或者[]error。若返回前者,对其继续进行比较;若返回后者,遍历其元素,对它们逐个进行比较。只要出现任意一个匹配即可终止比较。
As
func As(err error, target any) bool { /*...*/ }
若err错误树中包含匹配target错误的错误,将target设为该错误,返回true。类似Is方法。
重点:匹配是指错误具体值可以赋给target或者实现了As(interface{}) bool方法且As(target)返回true。
注意:type any = interface{}。若err非空且target不是指向实现了error或any接口的类型的非空指针,则panic。
Join
func Join(errs ...error) error { /*...*/ }
将所有errs错误包装成一个错误error(joinError)。若所有错误都是空,则返回空。
重点:非空结果实现了Unwrap() []error方法,错误内容为各错误内容的拼接,用换行符拼接。
注意:空的错误会被丢弃。
结构
errorString
type errorString struct {s string
}
是error接口的简单实现。s表示错误的内容。
errorString方法
Error
func (e *errorString) Error() string {return e.s
}
实现error接口。返回错误内容。
joinError
type joinError struct {errs []error
}
是error接口的一种实现,表示由多个错误拼接的错误。errs表示这多个错误的切片。
joinError方法
Error
func (e *joinError) Error() string {var b []bytefor i, err := range e.errs {if i > 0 {b = append(b, '\n')}b = append(b, err.Error()...)}return string(b)
}
实现error接口。返回用换行符拼接的错误的内容。
Unwrap
func (e *joinError) Unwrap() []error {return e.errs
}
返回此错误的拆包结果([]error)。
变量
ErrUnsupported
var ErrUnsupported = New("unsupported operation")
表示操作不支持的错误。
函数、方法不应该返回此错误,而应该返回包含一个恰当上下文的错误,该上下文满足
errors.Is(err, errors.ErrUnsupported),可通过直接包装ErrUnsupported,或实现Is方法来实现该错误。
errorType
var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
error元素的类型。
总结
新人源码理解,望大家多多指点。