Go 中errors包详解
前言
在 Golang 中,errors 包是用于处理错误的标准库, errors 包提供的功能比较简单,使用起来非常方便。接下来就具体讲解一下 errors 包提供的几个函数。
errors.New
func New(text string) error
错误处理是开发过程中必不可少的,使用 errors.New
函数可以创建一个表示特定错误的对象。接受一个字符串类型的参数(用于描述错误信息),返回一个 error
类型的值。例如:
func main() {
err := errors.New("invalid input")
fmt.Printf("err: %s", err)
}
error
类型是 builtin 包中定义的一个接口,定义如下:
type error interface {
Error() string
}
可以看出此接口定义了一个基本的 Error 方法,用于返回错误的描述信息。
errors.Is
func Is(err, target error) bool
用于判断给定的错误是否是目标错误类型或者基于目标错误类型包装过的错误,会递归检查错误链,直到找到目标错误类型或者到达错误链的末尾。如果找到目标错误类型,则返回true
,否则返回false
。看个例子:
func main() {
err := errors.New("invalid input")
err1 := errors.New("invalid input")
err2 := fmt.Errorf("err2: [%w]", err) // 注意这里的谓词是 %w
fmt.Println(err2) // err2: [invalid input]
err3 := fmt.Errorf("err3: [%s]", err) // 注意这里的谓词是 %s
fmt.Println(err3) //err3: [invalid input]
fmt.Println(errors.Is(err1, err)) // false
fmt.Println(errors.Is(err2, err)) // true
fmt.Println(errors.Is(err3, err)) // false
}
因为 err
和 err1
都是使用 errors.New
函数创建的,所以使用 Is
判断会返回 false
。err2
是基于 err
包装出来的,所以使用 Is
判断会返回 true
。
errors.AS
func As(err error, target any) bool
用于将错误转换为特定类型的错误,As
函数会检查 err
是否是 target
指向的类型的实例,如果是,将该实例赋值给 target
并返回 true
。否则返回 false
。看个例子:
func main() {
err := &MyError{
Message: "This is a custom error",
}
var target *MyError
if errors.As(err, &target) {
fmt.Println("Custom error found:", target.Message)
} else {
fmt.Println("Custom error not found")
}
}
使用 errors.As
来检查 err
是否是 MyError 类型的实例,并将实例赋值给 target。运行一下示例看下效果。
这个功能通常用于处理不同类型的错误,根据错误的类型采取对应的处理方式。
errors.Unwrap
func Unwrap(err error) error
用于将一个错误对象展开,得到下一层错误对象,如果错误对象没有下一层错误对象,则返回 nil。看个例子:
func main() {
originalErr := errors.New("original error")
err := fmt.Errorf("error: %w", originalErr) // 这里对error包装了一层. 注意必须是%w
unwrappedErr := errors.Unwrap(err)// 对error去掉这一层包装
fmt.Println(unwrappedErr) // 输出: original error
}
使用 fmt.Errorf
函数将 originalErr
做了一层包装后得到 err
,然后通过使用 Unwrap
将 err
解包并得包装前的错误对象 originalErr
。需要注意的是 Unwrap
只能展开被 fmt.Errorf
包装的错误对象。如果想要展开其他类型的错误对象,可以使用类型断言操作符 .
进行类型断言。
error
包提供了一些简单易用的函数来处理和获取错误信息,借助 errors
包可以实现非常强大的错误处理功能。
fmt.Errorf
在开发Go应用时,我们经常需要处理错误。Go标准库提供了fmt.Errorf函数。
fmt.Errorf
是Go标准库中的函数,可以创建一个新的错误。这个函数接受一个格式化字符串和一些参数,返回一个新的错误:
err := fmt.Errorf("an error occurred: %s", err) // 这里用的%s, 是在定义一个新的错误
fmt.Errorf
的优点在于其支持格式化字符串,这使得我们可以方便地在错误信息中包含一些动态的数据。
Go 1.13 中引入的新特性使fmt.Errorf
通过%w
谓词包装错误,这样就可以保留原始错误的信息。
例如:
originalErr := errors.New("original error")
newErr := fmt.Errorf("an error occurred: %w", originalErr) // 注意这里是 %w
然而,尽管fmt.Errorf
可以保留原始错误的信息,但它并不会保留原始错误的堆栈跟踪信息。