这篇文章是关于“CockroachDBerrors库”[1]的系列文章的第1篇,“CockroachDBerrors库”实际上是Go的标准errors包的通用、开放源码的替代品。
那本篇文章主要谈论什么呢?
基本的Go错误:error是值
Go生态有一些非常流行、也非常基本的学习资源(文档):
ATourofGo:Errors[2]。这是Go的官方教程。GoByExample:errors[3]。GoByExample是一些系列文章,推荐给那些希望通过示例学习Go的朋友们。GolandDocs:ErrorsandExceptionhandlinginGoLang[4]。“GolangDocs”是一系列文章,它涵盖了Go中的常见软件模式。我们可以从这些文章中学到什么?
Go提供了一个预定义的接口类型error,定义如下://anerrorisanobjectwithan`Error()`method//whichdescribesthesituationthatoccurred.typeerrorinterface{Error()string}编写Go函数/方法的惯用方法是让它们在常规返回值之外,再返回一个error类型值,并在每个调用点上进行测试funcdiv(x,yint)(int,error){ify==0{return0,fmt.Errorf(boo)}returnx/y,nil}funcmain(){r,err:=div(3,2)iferr!=nil{fmt.Printf(woops:%v,err)return}fmt.Println(result:,r)}如上面的示例所示,fmt.Printf会知道如何调用error的Error()方法来显示错误文本。如果错误是通过%s、%q、%x/%X打印的,它也会这样做。error也是链表
如果你还不知道DaveCheney[5]是谁,现在是时候去了解下这位及其高产的Go大师程序员。
年,Dave创建了pkg/errors包(源代码[6],文档[7]),随后在年东京举行的GoCon春季会议上展示了它。下面这篇文章用散文的形式解释了这个故事:
DaveCheney:优雅的处理错误,而不仅仅只是检查错误[8]
以下是Dave提到的主要创新:
Goerror对象像链表一样构建,而且是不可变的。err在任何时候都会指向列表的头部。在首次发生错误时,将构造一个原子或叶错误对象,该对象将在列表的尾部。当错误通过调用堆栈和软件组件返回时,通过向错误添加更多层、在现有错误列表的头部push更多列表元素或包装器来增加错误。这在实践中给我们什么启发呢?主要用途是向错误对象添加消息前缀,以给出有关错误发生在哪的更多上下文。例如:
import(fmtgithub.