• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

go 错误 异常

武飞扬头像
nicepainkiller
帮助1

自定义错误

 Go语言中  错误使用内建的 error 类型表示, error类型是一个接口类型:定义如下:

 error 有一个 Error() 的方法‘所有实现该接口的类型 都可以当做一个错误的类型;Error()方法输入具体错误描述,在打印错误时 可以调用 Error() 来输出错误

  1.  
    type error struct {
  2.  
    Error() string
  3.  
    }

对于简单的数据类型,一个 println 就可以了,

但是对于复杂类型 我们可以通过继承接口的方式 灵活的方式进行:

例如一个计算面积的函数:需要判断输入是否合法:比如输入负数则报错!

  

方式1:

  1.  
    //计算面积
  2.  
    //输入两个数 返回 面积和错误
  3.  
    func area(a, b int) (int, error) {
  4.  
    if a < 0 || b < 0 {
  5.  
    //第一种
  6.  
    //return 0, errors.New("计算长度 不能为负数")
  7.  
    //第二种
  8.  
    return 0, fmt.Errorf("计算长度 不能为负数; 长度%d,宽度%d 不能小于0", a, b)
  9.  
    //return 0, &areaError{"计算长度 不能为负数", a, b}
  10.  
    }
  11.  
    return a * b, nil
  12.  
    }
  13.  
     
  14.  
     
  15.  
    //调用:
  16.  
     
  17.  
    a := 20
  18.  
    b := -56
  19.  
     
  20.  
    r, err := area(a, b)
  21.  
    if err != nil {
  22.  
    fmt.Println(err)
  23.  
    return
  24.  
    }
  25.  
    fmt.Println("area:", r)
  26.  
     
  27.  
    输入:
  28.  
    计算长度 不能为负数
  29.  
     
  30.  
    计算长度 不能为负数; 长度20,宽度-56 不能小于0
学新通

  

方式2:

  1.  
    //定义错误结构体
  2.  
    type areaError struct {
  3.  
    err string //错误描述
  4.  
    length int //宽度
  5.  
    width int //长度
  6.  
    }
  7.  
    //实现一个接口
  8.  
    func (e *areaError) Error() string {
  9.  
    //return fmt.Sprintf("length %d, width %d", e.length, e.width)
  10.  
    return e.err
  11.  
    }
  12.  
     
  13.  
     
  14.  
    //求面积函数
  15.  
    func area(a, b int) (int, error) {
  16.  
    if a < 0 || b < 0 {
  17.  
    return 0, &areaError{"计算长度 不能为负数", a, b}
  18.  
    }
  19.  
    return a * b, nil
  20.  
    }
  21.  
     
  22.  
     
  23.  
    //调用:
  24.  
    a := 20
  25.  
    b := -56
  26.  
     
  27.  
    r, err := area(a, b)
  28.  
    //写法1
  29.  
    if err != nil {
  30.  
    if err, ok := err.(*areaError); ok {
  31.  
    fmt.Printf("length %d or width %d is less than zero\n", err.length, err.width)
  32.  
    fmt.Println(err)
  33.  
    return
  34.  
    }
  35.  
    fmt.Println(err)
  36.  
    return
  37.  
    }
  38.  
    fmt.Println("area:", r)
  39.  
     
  40.  
     
  41.  
    输出:
  42.  
    length 20 or width -56 is less than zero
  43.  
    计算长度 不能为负数
学新通

方式3:

  1.  
    //定义结构体和 函数
  2.  
    type areaError struct {
  3.  
    err string //错误描述
  4.  
    length int //宽度
  5.  
    width int //长度
  6.  
    }
  7.  
     
  8.  
    func (e *areaError) Error() string {
  9.  
    //return fmt.Sprintf("length %d, width %d", e.length, e.width)
  10.  
    return e.err
  11.  
    }
  12.  
     
  13.  
    func (e *areaError) widthNegative() bool {
  14.  
    return e.width < 0
  15.  
    }
  16.  
     
  17.  
    func (e *areaError) lengthNegative() bool {
  18.  
    return e.length < 0
  19.  
    }
  20.  
     
  21.  
     
  22.  
    //面积函数的定义
  23.  
    func area(length, width int) (int, error) {
  24.  
    err := ""
  25.  
    if length < 0 {
  26.  
    err = "length is negative"
  27.  
    }
  28.  
    if width < 0 {
  29.  
    err = "width is negative"
  30.  
    }
  31.  
    if err != "" {
  32.  
    return 0, &areaError{err: err, length: length, width: width}
  33.  
    }
  34.  
    return length * width, nil
  35.  
    }
  36.  
     
  37.  
     
  38.  
     
  39.  
    //调用:
  40.  
    a := 20
  41.  
    b := -56
  42.  
     
  43.  
    r, err := area(a, b)
  44.  
    if err != nil {
  45.  
    if err, ok := err.(*areaError); ok {
  46.  
    if err.lengthNegative() {
  47.  
    fmt.Println("Length is error :", err.length)
  48.  
    }
  49.  
    if err.widthNegative() {
  50.  
    fmt.Println("width is error :", err.width)
  51.  
    }
  52.  
    fmt.Printf("length:%d, width:%d\n", err.length, err.width)
  53.  
    return
  54.  
    }
  55.  
    fmt.Println(err)
  56.  
    }
  57.  
    fmt.Println("area:", r)
  58.  
     
  59.  
     
  60.  
    //输出:
  61.  
    width is error : -56
  62.  
    length:20, width:-56
学新通

异常

异常和错误 是两个不同的概念,容易混淆:

  • 错误是指:在有可能出现问题的地方,出现了问题
  • 异常是指:在不应该出现问题的地方,出现了问题

go 中的处理异常的主要有两种

  1. panic会导致程序会终止,在编写程序的时候 尽量使用错误; 只有在程序不能继续进行下去的时候在使用  panic,在发生 panic 的时候使用 recover 防止程序终止

    1.  
      // 会导致程序会终止,在编写程序的时候 尽量使用 错误; 只有在程序不能继续进行下去的时候在使用: panic, recover
    2.  
      func myTest() {
    3.  
      defer fmt.Println("myTest defer")
    4.  
      panic("myTest panic")
    5.  
      }
    6.  
       
    7.  
       
    8.  
      func main() {
    9.  
      defer fmt.Println("main defer")
    10.  
      myTest()
    11.  
      fmt.Println("main ...")
    12.  
      }
    13.  
       
    14.  
       
    15.  
      输出:带错误码的异常中断,并且程序没有执行完整; 没有打印 fmt.Println("main ...")
    16.  
       
    17.  
      myTest defer
    18.  
      main defer
    19.  
      panic: myTest panic
    20.  
       
    21.  
      goroutine 1 [running]:
    22.  
      main.myTest()
    23.  
      D:/awesomeProject/grammar/chapter08/main.go:18 0x73
    24.  
      main.main()
    25.  
      D:/awesomeProject/grammar/chapter08/main.go:7 0x70
    26.  
       
    27.  
      Process finished with the exit code 2
    28.  
       
    学新通
  2. recover recover 类似与其他语音 try catch但是它只有在 相同的协程中才能 recover到异常,继续执行代码 不至于奔溃

    1.  
      // 在发生 panic 的时候, recover 防止程序终止
    2.  
      // recover 类似与 try catch 只有在相同的协程中才能 recover到异常,继续执行代码 不至于奔溃
    3.  
      func outOfArray(x int) {
    4.  
      defer func() {
    5.  
      if err := recover(); err != nil {
    6.  
      fmt.Println(err)
    7.  
      }
    8.  
      }()
    9.  
       
    10.  
      var array [5]int
    11.  
      array[x] = 1
    12.  
      }
    13.  
       
    14.  
       
    15.  
       
    16.  
      func main() {
    17.  
      outOfArray(6)
    18.  
      fmt.Println("main ...")
    19.  
       
    20.  
      }
    21.  
       
    22.  
      输出: 带错误输出,并且程序继续往下执行 (执行完整) 输出 fmt.Println("main ...")
    23.  
       
    24.  
      runtime error: index out of range [6] with length 5
    25.  
      main ...
    26.  
       
    27.  
      Process finished with the exit code 0
    学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfhkij
系列文章
更多 icon
同类精品
更多 icon
继续加载