错误
错误error是接口类型
go中没有try{},原因是鼓励工程师解决掉错误,而不是忽略他,不过会让代码变繁琐。
2种创建error的方式
第一种:用errors去new
func main() {
errr := errors.New("创建错误的方法1")
fmt.Println(errr)
err := age(-1)
fmt.Println(err)
}
func age(a int) error {
if a < 0 {
return errors.New("年龄输入不合法")
}
return nil
}
第二种:用fmt创建
func main() {
errr2 := fmt.Errorf("我是一个错误2")
fmt.Println(errr2)
errr3 := fmt.Errorf("我是一个错误%d", 500)
fmt.Println(errr3)
}
这种创建错误的方式,可以增加一个参数。
可以通过断言error来判断错误,并进行处理
如:
自定义错误类型
可以自己定义一个错误类型,
1.先创建一个结构体
2.让结构体实现Error()方法
type myerror struct { //创建自定义错误结构体
msg string
code int
}
func (m myerror) Error() string {
return fmt.Sprint("错误信息:", m.msg, " 错误码:", m.code)
//实现Error,这样myerror才是Error类型,并定义了错误类型的内容。
}
func test(i int) (int, error) { //创建一个测试方法,返回值是int和error类型
if i != 0 {
err0 := &myerror{"非零数据", 500}
return i, err0
//由于10行myerror实现了Error的原因,myserror也可以作为Error类型,返回的err是实例化后的myerror
}
return i, nil
}
func main() {
i, err := test(1) //测试,正常应该返回err0 err0 := myerror{"非零数据", 500}
if err != nil {
fmt.Println(err)
//没有返回 err0,而是返回错误信息:非零数据 错误码:500,说明是myerror已经属于错误类,返回的err0自动被错误类加工了。
myerr, ok := err.(*myerror)
//断言确定 err的是不是我们指定的类型
if ok {
fmt.Println(myerr.msg, myerr.code) //非零数据 500
}
} else {
fmt.Println(i, "是零")
}
}
异常
关键字painc()
异常后会继续异常之前的defer 代码执行完毕后结束。
异常之后的代码不会继续执行。
func main() {
defer fmt.Println(1)
defer fmt.Println(2)
test(1)
defer fmt.Println(3)
}
func test(int2 int) {
if int2 == 1 {
panic("异常啦")
}
}
关键字recover()
作用是捕获异常,必须配合defer使用。
recover()没有参数,不过有返回值就是paninc传递的值