这次 errors 包算重量级更新。很有更能把以前的一些设计模式给推到。下面聊下用法。
以前返回一个错误,想要保存 error 链,还要定义结构体保存以前的 error 信息。感兴趣看下 syscal.ECONNREFUSED 如何封装到 url.Error 的。现在只要%w 就行
err = fmt.Errorf("第二层错误信息 %w", err)
如果是 fmt.Errorf("%w", err) 定义的错误链可以通过
e = errors.Unwrap(e) //解包错误
装包和解包错误是一一对应的,一次 Unwrap 调用,解一次 fmt.Errorf("%w", err)调用
package main
import (
"errors"
"fmt"
)
func main() {
var e, first error
first = errors.New("head")
e = fmt.Errorf("第一层错误:%w", first)
e = fmt.Errorf("第二层错误:%w", e)
e = fmt.Errorf("第三层错误:%w", e)
e = fmt.Errorf("第四层错误:%w", e)
//解包错误
e = errors.Unwrap(e)
fmt.Printf("%s\n", e)
//解包错误
e = errors.Unwrap(e)
fmt.Printf("%s\n", e)
//解包错误
e = errors.Unwrap(e)
fmt.Printf("%s\n", e)
//解包错误
e = errors.Unwrap(e)
fmt.Printf("%s\n", e)
}
/*
第三层错误:第二层错误:第一层错误:head
第二层错误:第一层错误:head
第一层错误:head
head
*/
if err == os.ErrNotExistF {
}
以前只有一个错误,现在是错误链表,要通过 errors.Is 遍历判断
b := errors.Is(err, os.ErrNotExist)
fmt.Printf("%t\n", b)
if _, err := os.Open("non-existing"); err != nil {
var pathError *os.PathError
if errors.As(err, &pathError) {
fmt.Println("Failed at path:", pathError.Path)
} else {
fmt.Println(err)
}
}
errors 包的一些姿势还要等长时间使用才能完全开发出来,欢迎 v 友提出想法,一起学习。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.