zoukankan      html  css  js  c++  java
  • 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 关键字修饰的函数,会在主函数退出前被执行。
  • 相关阅读:
    singleton模式 在软件开发中的运用
    State Pattern
    闲话闲说——关于异常
    程序人生
    Event
    SerialPort实现modem的来电显示
    利用枚举进行状态的设计
    职责链模式的运用
    我对当前项目的一些看法
    SHAREPOINT 2007 网站模板(解决方案)安装和卸载
  • 原文地址:https://www.cnblogs.com/isungge/p/15111133.html
Copyright © 2011-2022 走看看