文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
自定义 Error
error
是一个 interface
,所以在实现自己的包的时候,通过定义实现此接口的结构,就可以实现自己的错误定义,请看来自 Json 包的示例:
type SyntaxError struct {
msg string // 错误描述
Offset int64 // 错误发生的位置
}
func (e *SyntaxError) Error() string { return e.msg }
Offset
字段在调用 Error
的时候不会被打印,但可以通过类型断言获取错误类型,然后可以打印相应的错误信息,请看下面的例子:
if err := dec.Decode(&val); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf("%s:%d:%d: %v", f.Name(), line, col, err)
}
return err
}
需要注意的是,函数返回自定义错误时,返回值推荐设置为 error
类型,而非自定义错误类型,特别需要注意的是不应预声明自定义错误类型的变量。例如:
func Decode() *SyntaxError { // 错误,将可能导致上层调用者 err!=nil 的判断永远为 true。
var err *SyntaxError // 预声明错误变量
if 出错条件 {
err = &SyntaxError{}
}
return err // 错误,err 永远等于非 nil,导致上层调用者 err!=nil 的判断始终为 true
}
原因见 http://golang.org/doc/faq#nil_error
(需科学上网)
上面例子简单的演示了如何自定义 Error 类型。但是如果还需要更复杂的错误处理呢?此时,来参考一下 net 包采用的方法:
package net
type Error interface {
error
Timeout() bool // Is the error a timeout?
Temporary() bool // Is the error temporary?
}
在调用的地方,通过类型断言 err
是不是 net.Error
,来细化错误的处理,例如下面的例子,如果一个网络发生临时性错误,那么将会 sleep 1 秒之后重试:
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论