Errors
Overview
errors包实现了处理错误函数的实现 New函数用于创建带文本消息上下文的错误 Unwrap,Is,As函数工作于封装了其他错误的errors,一个错误封装另一个错误,如果它含有下面的方法Unwrap() error
如果e.Unwrap返回一个non-nil error w,则表示e封装了错误w Unwrap解包封装的错误,如果参数含有Unwrap方法,将会调用它,否则会返回nil 一个简单的方式创建封装的错误是调用 fmt.Errorf ,对错误参数应用%w动词errors.Unwrap(fmt.Errorf("... %w ...", ..., err, ...))
return err
Is持续的解包第一个参数直到找到一个错误匹配第二个参数,它判断是否找到匹配,它应该比直接持续简单相等判断更优先使用:
if errors.Is(err, os.ErrExist)
优先于
if err == os.ErrExist
因为err封装了os.ErrExist这种比较将会成功
As持续的解包第一个参数直到找到一个错误能够被赋值给第二个参数(必须是指针),如果成功,则进行赋值并返回true,否则返回false 形式如下:var perr *os.PathError
if errors.As(err, &perr) {
fmt.Println(perr.Path)
}
优先于
if perr, ok := err.(*os.PathError); ok {
fmt.Println(perr.Path)
}
因为这种形式将会成功如果错误封装了*os.PathError
函数(Functions)
func As(err error, target interface{}) bool
Example
package main
import (
"errors"
"fmt"
"os"
)
func main() {
if _, err := os.Open("non-existfile"); err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
fmt.Println("Failed at Path: ", pathErr.Path)
} else {
fmt.Println(err)
}
}
}
func Is(err, target error) bool
Example
package main
import (
"errors"
"io"
"fmt"
)
type ReadAtEnd struct {
id string
}
// 实现error interface
func (r *ReadAtEnd) Error() string {
return fmt.Sprintf("%s: read at end", r.id)
}
func (r *ReadAtEnd) Unwrap() error {
return io.EOF
}
func main() {
var r *ReadAtEnd = &ReadAtEnd {
id: "frist error",
}
if errors.Is(r, io.EOF) {
fmt.Println("read at eof")
} else {
fmt.Println(r.Error())
}
}
func New(text string) error
New函数返回一个有给定文本格式化的错误,每次调用New函数的错误都是有区别的,尽管它们有相同的文本Example
package main
import (
"fmt"
"errors"
)
func main() {
err := errors.New("random error")
if err != nil {
fmt.Print(err)
}
}
func Unwrap(err error) error
解包错误
Next Post