Go通关07:错误处理,如何通过error/panic处理错误?

Go通关07:错误处理,如何通过error/panic处理错误?

错误

在Go语言中,错误并不是非常严重,它是可以预期的,可以返回错误给调用者自行处理。

error 接口

在Go语言中,错误是通过内置的error接口来表示的,它只有一个Error方法来返回错误信息:

type error interface {
  Error() string
}

这里演示一个错误的示例:

func main() {
   i,err := strconv.Atoi("a")
   if err != nil {
      fmt.Println(err)
   }else {
      fmt.Println(i)
   }
}
  • 示例故意使用错误的字符串“a”来转为整数,所以这里会打印错误信息:
    strconv.Atoi: parsing "a": invalid syntax
  • 一般,error接口在当函数或方法调用时遇到错误时进行返回,且为第二个返回值,这样调用者就可以根据错误来自行处理。

error 工厂函数

我们可以使用 errors.New 这个工厂函数来生成错误信息,它接收一个字符串参数,返回一个error接口。

func test(m,n int) (int, error) {
  if m > n {
    return m,errors.New("m大于n")
  }else {
    return n,nil
  }
}

当m大约n的情况下,返回一个错误信息。

自定义 error

上面工厂函数只能传递一个字符串来返回,要想携带更多信息,这时候可以使用自定义error:

type testError struct {
   errorCode int //错误码
   errorMsg string //错误信息
}
func (t *testError) Error() string{
   return t.errorMsg
}

这里自定义error,它可以返回更多信息:

return m, &testError{
   errorCode: 1,
   errorMsg:  "m大于n"}

上面通过字面量方式创建*testError 来返回。

error 断言

通过error断言来获取返回的错误信息,断言可以将error接口转为自己定义的错误类型:

res, err := test(2,1)
if e,ok := err.(*testError);ok {
  fmt.Println("错误码:",e.errorCode,",错误信息:",e.errorMsg)
} else {
  fmt.Println(res)
}

Panic 异常

Go语言是一门静态语言,很多错误可以在编译的时候进行捕获,不过对于数组越界访问、不同类型强制转换这种,会在运行时候才会引起panic异常。
我们也可以手动来抛出 panic 异常,这里以连接mysql数据库为例:

func connectMySQL(ip,username,password string){
   if ip =="" {
      panic("ip不能为空")
   }
   //省略其他代码
}
  • 在以上函数中,如果ip地址为空,会抛出 panic 异常。
  • panic 是Go语言内置函数,可以接收 interface{} 类型的参数,也就是说任何类型的值都是可以传递给 panic 函数的:
func panic(v interface{})

interface{} 表示空接口,代表任意类型。
panic 是一种非常严重的错误,会使程序中断执行,所以 如果不是影响程序运行的错误,使用 error 即可

Recover 捕获 Panic 异常

一般我们不对panic异常做处理,但是如果有一些需要在程序崩溃前做处理的操作,可以使用内置的 recover 函数来恢复 panic 异常。
程序 panic 异常崩溃的时候,只有defer修饰的函数才会被执行,所以 recover 函数要结合 defer 关键字一起使用:

func main() {
   defer func() {
      if p:=recover();p!=nil{
         fmt.Println(p)
      }
   }()
   connectMySQL("","root","123456")
}

recover 函数捕获了 panic 异常,打印:recover 函数返回的值就是通过 panic 函数传递的参数值。 ip不能为空

  • recover 函数的返回值就是 panic 函数传递的参数值。
  • defer 关键字修饰的函数,会在主函数退出前被执行。
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » Go通关07:错误处理,如何通过error/panic处理错误?