玩转Go语言之捕获异常

1.异常处理提示用户:

func main() {
   
   if res, err := dev(10,0); err == nil {
      fmt.Println(res)
   }else {
      fmt.Println(err)
   }
   
}

func dev(a int, b int) (res int, err error) {
   if b == 0 {
      err = fmt.Errorf("除数不能为0")
      err = errors.New("除数不能为0")
   }else {
      res = a/b
   }
   return res,err
}复制代码

总结:

1.什么是异常?
不按照我们期望执行的都可以称之为异常

2.在Go语言中如何处理异常?
一种是程序发生异常时, 将异常信息反馈给使用者
  一种是程序发生异常时, 立刻退出终止程序继续运行

3.将异常信息反馈给使用者
创建方式一: fmt.Errorf("提示的内容")
创建方式二: errors.New("提示的内容")
注意点: 本质上两个方法底层的实现原理都是一样的

package builtin中定义了一个接口
type error interface {
   Error() string
}

package errors中定义了一个结构体
type errorString struct {
   s string
}
errorString结构体实现了builtin中定义的接口
func (e *errorString) Error() string {
   return e.s
}
所以errorString结构体实现了error接口

func New(text string) error {
   return &errorString{text}
}复制代码

2.异常处理终止程序

func main() {
   /*
   一种是程序发生异常时, 立刻退出终止程序继续运行

   终止程序也分为两种:
   1.系统自动终止
   2.我们手动终止 (企业开发不常用)
   格式: panic("提示信息")
    */

   // 系统自动终止
   //arr := [3]int{1, 3, 5}
   //for i := 0; i < 20; i++ {
   // fmt.Println(arr[i])
   //}

   res := div(10, 0)
   fmt.Println(res)
}
// 除法运算
func div(a, b int) (res int) {
   if b == 0 {
      // 手动终止程序
      panic("除数不能为0")
   }else{
      res = a / b
   }
   return
}复制代码

3.异常恢复:

func main() {
   /*
   1.程序不要随意被终止, 只要不是程序不能运行了, 就尽量让改程序继续保持运行

   2.在Go语言中如果panic异常, 那么可以通过defer和recover来实现panic异常的捕获, 让程序继续执行

   注意点:
   1.defer和recover必须在panic抛出异常之前定义
   2.panic异常会随着函数的调用栈向外传递
   例如: A函数调用了B函数, B函数调用了C函数
         如果在C函数中抛出了一个panic异常, 那么这个异常会一层一层的传递到B和A
         也就是在B和A函数中也能捕获到这个异常
    */

   defer func() {
      // defer无论所在的函数是正常结束,还是异常结束都会被执行
      // recover可以捕获panic异常
      if err := recover(); err != nil{
         fmt.Println("recover捕获到了", err)
      }
   }()

   res := div(10, 0)
   fmt.Println(res)
}
// 除法运算
func div(a, b int) (res int) {
   // 在当前函数中捕获
   //defer func() {
   // // defer无论所在的函数是正常结束,还是异常结束都会被执行
   // // recover可以捕获panic异常
   // if err := recover(); err != nil{
   //    fmt.Println("recover捕获到了", err)
   // }
   //}()
   if b == 0 {
      // 手动终止程序
      panic("除数不能为0")
   }else{
      res = a / b
   }
   // 无效
   //defer func() {
   // // defer无论所在的函数是正常结束,还是异常结束都会被执行
   // // recover可以捕获panic异常
   // if err := recover(); err != nil{
   //    fmt.Println(err)
   // }
   //}()
   return
}复制代码

4.异常注意点:

func main() {

   /*
   捕获异常注意点:
   1.同一个函数中, 多个panic异常, 只有第一个会被捕获
    */
    /*
   defer func() {
      if err := recover(); err != nil{
         fmt.Println(err) // 异常1
      }
   }()
   panic("异常1")
   panic("异常2")
   panic("异常3")
   panic("异常4")
    */
    test2()
}
func test2()  {
   // 如果有异常写在defer中, 但是defer后面还有其它异常, 那么捕获到的是其它的异常
   // 如果其它异常是写在defer前面, 那么和同一个函数中, 多个panic异常, 只有第一个会被捕获
   defer func() {
      if err := recover(); err != nil{
         fmt.Println(err) // 异常B
      }
   }()

   defer func() {
      panic("异常B")
   }()
   panic("异常C")
}复制代码

代码:https://github.com/codeXiaoQiang/Go-language


转载于:https://juejin.im/post/5badc42d5188255c7e4013f4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值