go语言error
相信大家在之前的例子也看到,我们会多次用到 error 这个东西,尤其是在函数的返回值上,由于 go 的函数支持多返回值,所以一般会用 error 作为其中一个返回值,代表该函数执行过程中或者逻辑有出错,那究竟 error 是个什么东西呢,下面我们就来一探究竟。
error是什么
error其实是golang的一个接口类型,就是一个普通的接口,并且也不会携带任何的堆栈信息。
接口的定义如下:
type error interface {
Error() string
}
通常我们会使用errors.New()或者fmt.Errorf()来返回一个error对象,但是需要注意,通过这两种方式返回的error对象都是不可以进行比较的,因为errors.New()返回的其实是一个地址,不能用来做等值判断,如果要是先等值判断,需要自己实现,而fmt.Error()的内部其实也是用到了errors.New()。
errors.New()接口实现:
func New(text string) error {
return &errorString{text}
}
fmt.Errorf()实现:
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
}
代码展示:
package main
import "fmt"
// 定义一个正数自加的函数,当传入的整数小于等于0的时候报错
func getPositiveSelfAdd(num int) (int,error) {
if num <=0 {
return -1,fmt.Errorf("num is not a positive number")
}
return num+1,nil
}
func main() {
num1,err1 := getPositiveSelfAdd(1)
fmt.Printf("nums is %d, err is %v\n",num1 ,err1)
num2,err2 := getPositiveSelfAdd(-2)
fmt.Printf("nums is %d, err is %v\n",num2 ,err2)
err3 := errors.New("hello")
err4 := errors.New("hello")
fmt.Println(err3==err4)
fmt.Println(err3.Error()==err4.Error())
}
运行结果:
nums is 2, err is <nil>
nums is -1, err is num is not a positive number
false
true
通过阳历可以看到,通过上述方法创建出的两个error对象是不能直接比较的,即便是error信息一样,也会返回false,如果我们想要比较,可以通过Error()方法拿到其中的error字符串信息,比较字符串。
自定义error对象
go语言内置的error创建方法非常简单,也易上手,但是有时候并不能满足我们的业务要求,因为他只返回了错误信息,类似于error的message,但是很多时候我们业务上还需要错误码,即error code。所以,很多时候我们可以自定义error对象
type MyError struct {
code int
msg string
}
对象定义完之后,接下来只需要实现error接口的Error方法即可,这样,我们就自定义了一个同时带有错误码和错误信息的error对象。
下面请看具体例子:
package main
import "fmt"
type MyError struct {
code int
msg string
}
func (m MyError) Error() string {
return fmt.Sprintf("code:%d,msg:%v", m.code, m.msg)
}
func NewError(code int, msg string) error {
return MyError{
code: code,
msg: msg,
}
}
func Code(err error) int {
if e, ok := err.(MyError); ok {
return e.code
}
return -1
}
func Msg(err error) string {
if e, ok := err.(MyError); ok {
return e.msg
}
return ""
}
func main() {
err := NewError(100, "test MyError")
fmt.Printf("code is %d, msg is %s", Code(err), Msg(err))
}
运行结果:
code is 100, msg is test MyError