Go接口--error接口

error接口

error接口和errors包

error接口很简单,它只是一个接口类型,不含一个返回错误消息的方法

1
2
3
type error interface{
Error() string
}

构造error最简单的方法是用errors.New,其返回一个包含错误消息的error类型

errors这个包也很简单,就只有四行代码

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
}
  • 额外定义一个errorString类型而不直接使用字符串是因为将来可能会对布局进行变更。
  • 满足error接口的类型是*errorString而不是errorString,确保每次调用errors.New分配到的实例都不同,这是因为不能仅仅因为字符串内容相同,就让两个error类型相同,例如
    1
    errors.New("EOF") == errors.New("EOF") // false

不过我们一般不直接调用errors.New,而是使用支持字符串格式化的fmt.Errorf

syscall.Errno错误类型

syscall.Errno也实现了error接口,主要是提供一个整数对应的错误类型映射,我们在自定义错误类型的时候,可以参考这个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package syscall


type Errno uintptr

func (e Errno) Error() string {
if 0 <= int(e) && int(e) < len(errors) {
s := errors[e]
if s != "" {
return s
}
}
return "errno " + itoa.Itoa(int(e))
}


var errors = [...]string{
1: "operation not permitted",
2: "no such file or directory",
3: "no such process",
4: "interrupted system call",
// ...
}
1
2
3
var err error = syscall.Errno(2)
fmt.Println(error) // no such file or directory
fmt.Println(error.Error()) // no such file or directory