The Go Blog

Go语言中的error类型

bantana
30 July 2015

introduction

Go语言中设计了一个专门的error类型来显示表达错误。

来看一个os包中的Open函数:

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

函数Open给定一个输入(name string), 返回2个值(指向文件的指针*File,和描述错误的error)

然后我们可以这样使用:

f, err := os.Open("filename.ext")

因此你就可以用如下判断(err是error类型)

if err != nil {
  // err, process error
}
// ok, continue use f

type error

错误类型是一个接口类型, 它有一个Error()方法,返回string。

type error是build in types。来看看类型声明:

godoc -src builtin error

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
    Error() string
}

记住nil value表示no error.

Error方法:

godoc -src errors Error

func (e *errorString) Error() string {
    return e.s
}

方法的接收者:

godoc -src errors errorString

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

errroString是errors包的私有struct类型,含有一个string的属性。 也就是说,errorString类型中是一个这样的值errorString{s string}。 在一般情况下,我们不需要实现自己的error struct, 可以使用errors.New function来构造一个error的值。

godoc -src errors New

// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}

godoc -src fmt Errorf

// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, a ...interface{}) error {
    return errors.New(Sprintf(format, a...))
}

根据Go的设计,你只需要实现Error() string方法就自动实现了type error interface。

go的error type一般用法

首先要牢牢记住error是一个type error interface. 然后Go中的function和method(带接收者的function)是first class function。 这样看到fmt.Println(err)就不会容易误解为err是string.

下面2个是等价的。

fmt.Println(err)
println(err.Error())

上面描述了type error interface的设计。下面来总结下一般如何使用。

大部分情况下只需要用errors.New。

比如一个整数除法:

func integerDivide(a , b int) (int, error) {
  if b == 0 {
    return 0, errors.New("除零错误,分母不能为0")
  }
  retrun a/b, nil
}

var a, b int = 5 , 2
result, err := integerDivide(a, b)
if err != nil {
  fmt.Println(err)
  // println(err.Error())
  return
}
fmt.Printf("integer divide: %v / %v = %v", a, b, result)

定制error struct

//todo

在自己的包中设计error interface

//todo

Related articles