Part1

builtin/builtin.go:260

Go 中的 error 类型就是一个普通的接口,普通的值。error 类型的定义位于 package builtin 中。

1
2
3
4
5
// 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
}

Part2

errors/errors.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package errors

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
return &errorString{text}
}

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

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

我们经常使用 errors.New() 来返回一个 error 对象。其实,errors.New() 返回的是内部 errorString 对象的指针。之所以返回指针,是为了防止两个 error 比较时产生意料之外的相等情况。

Part3

fmt/errors.go

fmt.Errorf 可以基于格式化字符串来生成 error 对象,函数内部实际调用了errors.New(s)方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Errorf formats according to a format specifier and returns the string as a
// value that satisfies error.
func Errorf(format string, a ...interface{}) error {
p := newPrinter()
p.wrapErrs = true
p.doPrintf(format, a)
s := string(p.buf)
var err error
if p.wrappedErr == nil {
err = errors.New(s)
} else {
err = &wrapError{s, p.wrappedErr}
}
p.free()
return err
}

Part4