You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// The error built-in interface type is the conventional interface for// representing an error condition, with the nil value representing no error.typeerrorinterface {
Error() string
}
日常使用经验
error 处理在日常编程中十分常用,官方对于错误处理也有指导性观点:
But remember: Whatever you do, always check your errors!
Go 源码 io Package 就预先定义了常见的错误,调用方可以 通过类似 err == EOF 操作来决定如何更准确的处理这个错误。
// ErrShortWrite means that a write accepted fewer bytes than requested// but failed to return an explicit error.varErrShortWrite=errors.New("short write")
// errInvalidWrite means that a write returned an impossible count.varerrInvalidWrite=errors.New("invalid write result")
// ErrShortBuffer means that a read required a longer buffer than was provided.varErrShortBuffer=errors.New("short buffer")
// EOF is the error returned by Read when no more input is available.// (Read must return EOF itself, not an error wrapping EOF,// because callers will test for EOF using ==.)// Functions should return EOF only to signal a graceful end of input.// If the EOF occurs unexpectedly in a structured data stream,// the appropriate error is either ErrUnexpectedEOF or some other error// giving more detail.varEOF=errors.New("EOF")
// ErrUnexpectedEOF means that EOF was encountered in the// middle of reading a fixed-size block or data structure.varErrUnexpectedEOF=errors.New("unexpected EOF")
// ErrNoProgress is returned by some clients of a Reader when// many calls to Read have failed to return any data or error,// usually the sign of a broken Reader implementation.varErrNoProgress=errors.New("multiple Read calls return no data or error")
二、使用语言来简化错误处理
《Errors are values》 这篇文章中用三段论的口吻着重提到:Values can be programmed, and since errors are values, errors can be programmed。使用 “编程的思维” 来处理 error,以下是日常业务中常见的代码,看起来重复又丑陋。
_, err=fd.Write(p0[a:b])
iferr!=nil {
returnerr
}
_, err=fd.Write(p1[c:d])
iferr!=nil {
returnerr
}
_, err=fd.Write(p2[e:f])
iferr!=nil {
returnerr
}
// and so on
基本定义
error
是 go 语言的内置类型,其定义很简单,只要实现Error() string
即可。日常使用经验
error
处理在日常编程中十分常用,官方对于错误处理也有指导性观点:如何优雅的使用
error
,导向性一定是能够快速的发现问题、定位问题,在此前提之上保持代码简洁、可读性强。一、预先定义错误
正确的使用
error
,一定是以快速定位错误为目标的。如果能知道是什么错误,那一定能够更好的处理这个错误。预先定义好可能出现的错误,让调用方有一个初步的预判是一个不错的方案。Go 源码 io Package 就预先定义了常见的错误,调用方可以 通过类似
err == EOF
操作来决定如何更准确的处理这个错误。二、使用语言来简化错误处理
《Errors are values》 这篇文章中用三段论的口吻着重提到:Values can be programmed, and since errors are values, errors can be programmed。使用 “编程的思维” 来处理 error,以下是日常业务中常见的代码,看起来重复又丑陋。
其实稍微加以结构化改造,代码就可以优雅一些,这个需要思考与设计。改造后的代码错误仅处理一次,如果一开始
write
方法就遇到了错误,后面write
方法将成为一个no-op
函数,但遇到的 error 被保留了下来。Go 1.13 以后的错误处理思路
Russ Cox 提出 experiment, simplify and ship,error 的处理改进也是吸收了许多社区里的实践经验,其中最主要的是 pkg/errors。errors 包使用十分广泛,但源码并不多,核心提供了如下能力:
WithMessage(err error, message string) error
构造类似 error chain,新创建一个 error,新 error 会关联传入的 errorWrap(err error, message string) error
同样是构建 error chain,但加入了错误 stack 信息(哪个文件哪一行报了错)Cause(err error) error
递归检索最顶层错误(也就是错误根因),直到遇到没有实现Cause() error
方法的 error总结下来,pkg/errors 在 Go 语言错误处理上提供了几个能力,简洁而优雅的处理了:
Cause
所做的鉴于社区经验,go 1.13 之后对 error 处理新增了几项支持:
Unwrap
方法, error 就像一条链一样,一个 wrap 另一个,Unwrap
方法返回其 wrap 的 errorIs
&As
,Is
用来替代err == SomeError
,As
用来替代switch e := err.(type)
fmt.Errorf
支持新的 Verb%w
,其会返回一个新的 error,该 error 的Unwrap
方法返回占位符中传入的 error参考文章
The text was updated successfully, but these errors were encountered: