前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >go 如何捕获异常

go 如何捕获异常

作者头像
王小明_HIT
发布2021-07-05 16:33:14
发布2021-07-05 16:33:14
1.4K00
代码可运行
举报
文章被收录于专栏:程序员奇点程序员奇点
运行总次数:0
代码可运行

什么是异常?

不按照我们期望执行的都可以称之为异常

在Go语言中如何处理异常?

  • 一种是程序发生异常时, 将异常信息反馈给使用者
  • 一种是程序发生异常时, 立刻退出终止程序继续运行

将异常信息反馈给使用者

  • 创建方式一: fmt.Errorf("提示的内容")
  • 创建方式二: errors.New("提示的内容")注意点: 本质上两个方法底层的实现原理都是一样的

package builtin中定义了一个接口

代码语言:javascript
代码运行次数:0
复制
type error interface {
   Error() string
}

package errors中定义了一个结构体

代码语言:javascript
代码运行次数:0
复制
type errorString struct {
   s string
}

errorString结构体实现了builtin中定义的接口

代码语言:javascript
代码运行次数:0
复制
func (e *errorString) Error() string {
   return e.s
}

所以errorString结构体实现了error接口

代码语言:javascript
代码运行次数:0
复制
func New(text string) error {
   return &errorString{text}
}

异常信息提示

代码语言:javascript
代码运行次数:0
复制
func TestThrowError(t *testing.T) {
 if res, err := div(10, 0); err == nil {
  fmt.Println(res)
 } else {
  fmt.Println(err)
 }
}

func div(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
}

运行结果:

代码语言:javascript
代码运行次数:0
复制
=== RUN   TestThrowError
除数不能为0
--- PASS: TestThrowError (0.00s)
PASS

异常处理终止程序

程序终止的方式:

  • 系统自动终止
  • 手动终止(企业级应用开发中不常用)格式 :panic("提示信息")
代码语言:javascript
代码运行次数:0
复制
func TestExceptionPanic(t *testing.T) {
 /*
    一种是程序发生异常时, 立刻退出终止程序继续运行
    终止程序也分为两种:
    1.系统自动终止
    2.我们手动终止 (企业开发不常用)
    格式: panic("提示信息")
 */
 // 系统自动终止
 //arr := [3]int{1, 3, 5}
 //for i := 0; i < 20; i++ {
 // fmt.Println(arr[i])
 //}

 res := div1(10, 0)
 fmt.Println(res)
}

// 除法运算
func div1(a int, b int) (res int) {
 if b == 0 {
  //手动终止程序
  panic("除数不能为0")
 } else {
  res = a / b
 }
 return res
}

异常恢复

  • 程序不要随意被终止,只要不是程序不能运行,需要建立让程序保持运行
  • 如果程序出现 panic 异常,可以通过 defer 和 recover 实现 panic 异常的捕获,让程序正常运行。
注意
  • defer 和 recover 必须要在 panic 之前被定义
  • panic 异常会随着函数的调用栈向外传递 A函数调用了B函数, B函数调用了C函数,如果在C函数中抛出了一个panic异常, 那么这个异常会一层一层的传递到B和A,也就是在B和A函数中也能捕获到这个异常
代码语言:javascript
代码运行次数:0
复制
func TestExceptionRecover(t *testing.T) {
 /*
    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() {
  if err := recover(); err != nil {
   fmt.Println("recover 捕获到了异常", err)
  }
 }()
 res := div2(10, 0)
 fmt.Println(res)

}

// 除法运算
func div2(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
}

运行结果:

代码语言:javascript
代码运行次数:0
复制
=== RUN   TestExceptionRecover
recover 捕获到了异常 除数不能为0
--- PASS: TestExceptionRecover (0.00s)
PASS

捕获异常注意点

同一个函数中,多个 panic 异常,只要第一个会被捕获

代码语言:javascript
代码运行次数:0
复制
func TestPanics(t *testing.T) {
 /*
    捕获异常注意点:
    1.同一个函数中, 多个panic异常, 只有第一个会被捕获
 */
 /*defer func() {
  if err := recover(); err != nil {
   fmt.Println(err) //异常1
  }
 }()

 panic("异常1")
 panic("异常2")
 panic("异常3")
 panic("异常4")*/
 panicfuc()
}

func panicfuc() {
 // 如果有异常写在defer中, 但是defer后面还有其它异常, 那么捕获到的是其它的异常
 // 如果其它异常是写在defer前面, 那么和同一个函数中, 多个panic异常, 只有第一个会被捕获

 defer func() {
  if err := recover(); err != nil {
   fmt.Println(err) // 异常B
  }
 }()

 defer func() {
  panic("异常B")
 }()

 panic("异常C")
}

运行结果

代码语言:javascript
代码运行次数:0
复制
=== RUN   TestPanics
异常B
--- PASS: TestPanics (0.00s)
PASS
欢迎关注公众号:程序员开发者社区

微信号:程序员开发者社区

博客:CSDN 王小明

关注我们,了解更多

关注后:回复 AI, 有惊喜

参考资料
  • https://juejin.cn/post/6844903685303205896
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是异常?
    • 在Go语言中如何处理异常?
    • 将异常信息反馈给使用者
    • 异常信息提示
    • 异常处理终止程序
    • 异常恢复
      • 注意
    • 捕获异常注意点
      • 欢迎关注公众号:程序员开发者社区
      • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档