Go error 接口

Go的标准库函数在发生错误时会返回error类型,比如常用的os.Open函数用来打开文件,错误时返回error:

func Open(name string) (*File, error)

那么究竟什么是error类型呢?其实很简单,error是一个接口,该接口只声明了一个方法Error(),返回值是string类型,用以描述错误:

type error interface {
    Error() string
}

如何创建自己的error呢?当然可以自己实现这个接口,比如:

package main

import "fmt"

type MyError struct {
    Desc string
}

func (myErr MyError) Error() string {
    return myErr.Desc
}

func doSomething() error {
    // ...
    return MyError{"Logic Error!"}
}

func main() {
    if err := doSomething(); err != nil {
        fmt.Println(err)
    }
}

但是更简单的方法是利用errors包中的New()函数直接创建error对象,errors包的内容仅有如下四行代码:

package errors
func New(text string) error { return &errorString{text} }
type errorString struct { text string }
func(e *errorString) Error() string { return e.text }

可以看到errors包的内部声明了一个 errorString 结构体,并用其中的text字段来表示错误描述,而不是直接用字符串来表示,这样做的好处是将错误描述封装了起来,防止我们在包外意外地改变错误描述。注意实现 error 接口的是 *errorString,而不是 errorString,这是为了让所有New返回的error对象都不相等:

fmt.Println(errors.New("EOF") == errors.New("EOF")) // false

一版情况下我们很少调用errors.New()来创建error对象,而是通过fmt包中提供的函数Errorf():

package fmt
import "errors"
func Errorf(format string, args ...interface{}) error {
    return errors.New(Sprintf(format, args...))
}

可以看到fmt.Errorf()也是通过errors.New()来创建error对象。

*errorString 可能是最简单的error对象,但并不是唯一的error对象,比如syscall包中的Errno也是一个实现了error接口的类型。在Unix实现中,Errno的Error()方法通过查找错误列表返回错误信息:

package syscall
type Errno uintptr
var errors = [...]string {
    1: "operation not permitted",
    2: "no such file or directory",
    // ...
}
func (e Errno) Error() string {
    if 0 <= int(e) && int(e) < len(errors) {
        return errors[e]
    }
    return fmt.Sprintf("errno %d", e)
}

参考自《Go程序设计语言》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值