Go异常处理机制panic和recover

这篇具有很好参考价值的文章主要介绍了Go异常处理机制panic和recover。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


recover


使用panic抛出异常后, 将立即停止当前函数的执行并运行所有被defer的函数,然后将panic抛向上一层,直至程序crash。但是也可以使用被defer的recover函数来捕获异常阻止程序的崩溃,recover只有被defer后才是有意义的。

func main() {

 print(123)

 print(456)
 panic("throw an error")

 print(678//IDE会有提示: Unreachable code

}

结果:

123456panic: throw an error

goroutine 1 [running]:
main.main()
    /Users/shuangcui/explore/panicandrecover.go:31 +0x67

使用recover()捕获异常:

func main() {

 print(123)

 defer func() {
  if err := recover(); err != nil {
   print("recover it")
  }
 }()

 print(456)
 panic("throw an error")

 print(678//IDE会有提示: Unreachable code

}

结果为:

123456recover it

如果有两个recover,则捕获异常的是后一个

func main() {

 print(123)

 defer func() {
  if err := recover(); err != nil {
   print("recover it")
  }
 }()

 defer func() {
  if err := recover(); err != nil {
   print("复原!")
  }
 }()

 print(456)
 panic("throw an error")

 print(678//IDE会有提示: Unreachable code

}

结果为:

123456复原!

panic之后的任何代码都不会继续执行


前提是panic不在if里面


package main

import "fmt"

func main() {
 defer_call()
 fmt.Println("333 Helloworld")
}

func defer_call() {
 defer func() {
  fmt.Println("11111")
 }()

 defer func() {
  fmt.Println("22222")
 }()

 defer func() {
  if r := recover(); r != nil {
   fmt.Println("Recover from r : ", r)
  }
 }()

 defer func() {
  fmt.Println("33333")
 }()

 fmt.Println("111 Helloworld")

 panic("Panic 1!")


    //使用panic抛出异常后, 将立即停止当前函数的执行并运行所有被defer的函数,然后将panic抛向上一层, 直至程序crash

    //但是也可以使用被defer的recover函数来捕获异常阻止程序的崩溃,recover只有被defer后才是有意义的。

 panic("Panic 2!"//panic1之后的panic2没有任何机会会被执行, panic2之后的任何代码更没有任何机会被执行

 fmt.Println("222 Helloworld")
}

输出为:

111 Helloworld
33333
Recover from r :  Panic 1!
22222
11111
333 Helloworld

对于goroutine中的panic,协程外面的recover是无法恢复的;goroutine中的recover,同样无法恢复协程外的panic


Go异常处理机制panic和recover,后端

但协程中的recover可以恢复协程中的panic

package main

import (
 "fmt"
 "time"
)

func main() {

 go func() {
  defer func() {
   if err := recover(); err != nil {
    fmt.Println("recover err:", err)
   }
  }()
  panic("里面出错了")
 }()

 //panic("外面出错了")

 time.Sleep(1 * time.Second)

}

输出为:

recover err 里面出错了


主方法中的recover,也可以恢复子方法里的panic


但如果go subfunc(),则同样无法捕获subfunc中的异常

func main() {

 fmt.Println(123)

 defer fmt.Println(999)

 defer func() {
  if err := recover(); err != nil {
   fmt.Println("恢复异常:",err)
  }

 }()
 subfunc()

}

func subfunc() {

 defer fmt.Println(888)
 panic("出现了bug")

 defer fmt.Println(456)

}

结果为:

123
888
恢复异常: 出现了bug
999



因为panic发生的时候,panic函数后面的语句都不会执行了,所以recover函数不能放在panic语句后面执行,而要放在defer函数中执行。

使用 panic 抛出异常后,函数执行将从调用 panic 的地方停止,如果函数内有 defer 调用,则执行 defer 后边的函数调用,如果 defer 调用的函数中没有捕获异常信息,这个异常会沿着函数调用栈往上传递,直到 main 函数仍然没有捕获异常,将会导致程序异常退出


如何区别使用 panic 和 error 两种方式?

惯例是:导致关键流程出现不可修复性错误的使用 panic ,其他使用 error 。

panic 和 recover 的组合有如下特性:

  • 有 panic 没 recover ,程序宕机。
  • 有 panic 也有 recover ,程序不会宕机,执行完对应的 defer 后,从宕机点退出当前函数后继续执行。



recover能捕获所有错误吗?


不能!

Go 有哪些无法恢复的致命场景?

  • 并发读写 map fatal error: concurrent map read and map write
  • 堆栈内存耗尽(如递归)
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc0200e1bf0 stack=[0xc0200e00000xc0400e0000]
fatal error: stack overflow
  • 将 nil 函数作为 goroutine 启动 fatal error: go of nil func value
  • goroutines 死锁 fatal error: all goroutines are asleep - deadlock!
  • 线程超过设置的最大限制 fatal error: thread exhaustion
  • 超出可用内存 fatal error: runtime: out of memory

总之 都会报fatal error:xxxxxxxx


拓展&参考:

golang panic和recover 实现原理[1]

Go 学习笔记(19)— 函数(05)[如何触发 panic、触发 panic 延迟执行、panic 和 recover 的关系][2]

Go 语言踩坑记——panic 与 recover[3]


参考资料

[1]

golang panic和recover 实现原理: https://blog.csdn.net/u010853261/article/details/102761955

[2]

Go 学习笔记(19)— 函数(05)[如何触发 panic、触发 panic 延迟执行、panic 和 recover 的关系]: https://blog.csdn.net/wohu1104/article/details/105571916

[3]

Go 语言踩坑记——panic 与 recover: https://xiaomi-info.github.io/2020/01/20/go-trample-panic-recover/

本文由 mdnice 多平台发布文章来源地址https://www.toymoban.com/news/detail-639655.html

到了这里,关于Go异常处理机制panic和recover的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Go 基础篇】Go语言中的defer和recover:优雅处理错误

    【Go 基础篇】Go语言中的defer和recover:优雅处理错误

    Go语言以其简洁、高效和强大的特性受到了开发者的热烈欢迎。在错误处理方面,Go语言提供了一种优雅的机制,即通过 defer 和 recover 组合来处理恐慌(panic)错误。本文将详细介绍Go语言中的 defer 和 recover 机制,探讨其工作原理和在实际开发中的应用。 在软件开发过程中,

    2024年02月10日
    浏览(10)
  • C++ 异常处理机制详解:轻松掌握异常处理技巧

    C++ 异常处理机制允许程序在运行时处理错误或意外情况。它提供了捕获和处理错误的一种结构化方式,使程序更加健壮和可靠。 异常: 程序在运行时发生的错误或意外情况。 抛出异常: 使用 throw 将异常传递给调用堆栈。 捕获异常: 使用 try-catch 块捕获和处理异常。 异

    2024年04月28日
    浏览(14)
  • java异常处理机制(二)之异常处理与捕获

    java异常处理机制(二)之异常处理与捕获

    1 Error(错误): 是指程序无法处理的错误,表示运行应用程序时比较严重的问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM(Java 虚拟机)出现的问题。 2 异常(Exception): 是指在程序执行时由于程序处理逻辑上的错误而导致程序中断的一种指令流。通俗的

    2024年02月05日
    浏览(11)
  • GO——recover

    定义 panic 改变程序控制流 立即停止当前函数剩余代码,调用defer 只会执行当前协程的defer recover 可以终止panic造成的程序崩溃 只能在defer中发挥作用 输出

    2024年01月25日
    浏览(8)
  • java异常处理机制(三)常见异常

    Java常见的异常包括但不限于以下几种: 1. NullPointerException(空指针异常):当试图调用实例方法或访问实例变量时,对象引用为 null 时抛出。 2. ArrayIndexOutOfBoundsException(数组越界异常):当访问数组中不存在的元素时抛出。 3. ClassCastException(类转换异常):当试图将对象强

    2024年02月05日
    浏览(12)
  • 爬虫异常处理:异常捕获与容错机制设计

    爬虫异常处理:异常捕获与容错机制设计

    作为一名专业的爬虫程序员,每天使用爬虫IP面对各种异常情况是我们每天都会遇到的事情。 在爬取数据的过程中,我们经常会遇到网络错误、页面结构变化、被反爬虫机制拦截等问题。在这篇文章中,我将和大家分享一些关于如何处理爬虫异常情况的经验和技巧。通过异常

    2024年02月11日
    浏览(10)
  • 后端项目开发:整合全局异常处理

    新建exception目录,用来进行自定义的全局异常处理。 (1)新建自定义的GlobalException基 类继承RuntimeException类,我们自定义的异常类全部需要继承GlobalException基类进行处理。 这里我们直接利用之前定义的错误码接口类。 (2)在exception目录下,新建GlobalExceptionHandler类,拦截异

    2024年02月11日
    浏览(12)
  • C# 异常处理机制和常见的异常类型

    在 C# 中,异常处理是一个非常重要的概念,它可以让我们在程序发生错误时进行有效的处理,使程序具备更好的鲁棒性。C# 异常处理机制基于 try-catch-finally 语句块,其基本用法如下: 在上面的代码中,try 块中的代码可能会抛出一些异常,如果发生异常,则会进入到相应的

    2023年04月21日
    浏览(14)
  • 【JAVA 异常处理机制】

    【JAVA 异常处理机制】

    在Java编程中,异常处理是一种重要的机制,用于处理程序运行时可能出现的错误和异常情况。异常处理机制可以帮助开发者优雅地处理异常,提高程序的健壮性和可靠性。 提示:以下是本篇文章正文内容,下面案例可供参考 java中所有错误的超类为:Throwable。其下有两个子类

    2024年02月11日
    浏览(11)
  • 异常处理机制

    异常处理机制

    概念:将后端的错误带到前端 使用步骤 申明一个类用于接收错误信息 添加注解 @RestControllerAdvice @ExceptionHandler 注意,添加的注解需要被扫描加载到容器中 常见的异常 框架内部抛出的异常:因使用不规范导致 数据层抛出的异常:外部服务器故障导致 业务层抛出异常:逻辑书

    2024年02月11日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包