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
}
可以看到,error
就是一个接口,其中包含Error() string
方法。从Error()
的返回值也可以推断出,出现错误也只是打印错误字符串而已。
从接口类型可以很自然的想到,我们可以实现自己结构的Error() string
方法,从而实现error
接口。
创建error
errors.New()函数
我们常使用errors.New
,这返回一个经过字符串填充过的errorString
结构,我们可以打印错误信息。
package main
import (
"errors"
"fmt"
)
func main() {
error := errors.New("this is a test")
if error != nil {
fmt.Println(error) // this is a test
fmt.Println(error.Error()) // this is a test
}
}
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
}
可以看到,New
接收一个字符串,填充并返回一个errorString
结构,而errorString
结构很简单,仅包含一个string
类型。
还可以看到,errorString
结构实现了自己的Error
方法,返回自己接收到的错误信息。
自定义结构实现error
可以看到之前的errorString
结构实现了自己的Error
方法,从而实现了error
接口。我们也可以自定义结构,实现自己的Error() string
方法从而实现error
接口。
package main
import "fmt"
type MyError struct {
name string
id int
}
// MyError 实现 Error 方法 ---> 实现 error 接口
func (e MyError) Error() string {
return fmt.Sprintf("%v: %v", e.name, e.id)
}
// MyError 实现了 error 接口,所以可以被转换为 error 类型
func getMyError() error {
return MyError{
name: "this is a test err",
id: 1,
}
}
func main() {
if err := getMyError(); err != nil {
fmt.Println(err)
}
// this is a test err: 1
}