当前位置: 首页 > news >正文

Go 语言 panic 和 recover 详解

panic() 和 recover() 是 Go 语言中用于处理错误的两个重要函数。panic() 函数用于中止程序并引发panic,而 recover() 函数用于捕获panic并恢复程序的执行。

什么是panic和recover?

panic

  • panic() 函数用于中止程序并引发panic。
  • panic() 函数可以接收一个参数,该参数将作为panic的原因。
  • 当发生panic时,程序将停止执行,并开始寻找最近的recover调用。
  • 如果找不到recover调用,程序将打印panic的原因并退出。

recover

  • recover() 函数用于捕获panic并恢复程序的执行。
  • recover() 函数可以接收一个参数,该参数将存储panic的原因。
  • 如果在发生panic时调用了recover,程序将继续执行,并且panic的原因将被存储在recover的第一个参数中。
func main() {defer func() {err := recover()if err != nil {fmt.Println("panic:", err)}}()panic("hello, panic!")
}

panic 的传播

 panic 函数会向上传播到调用它的 goroutine。如果 panic 函数没有被捕获,则会一直向上传播,直到遇到 defer 语句中调用的 recover() 函数,或者程序退出。

注意事项

跨协程失效

panic 和 recover 不能跨协程使用。这意味着在一个协程中发生的panic只能在同一个协程中通过 recover 捕获。如果在一个协程中发生了panic,而在另一个协程中调用了 recover,那么 recover 将无法捕获panic。参考如下代码:

func main() {defer println("in main")go func() {defer println("in goroutine")panic("")}()time.Sleep(1 * time.Second)
}

失效的崩溃恢复

如果在一个defer函数中发生了panic,那么该defer函数后面的语句将不会被执行。这意味着在defer函数中使用 recover 来捕获panic是无效的。

func main(){defer fmt.Println("main....")defer func() {err := recover()if err != nil {fmt.Println("panic:", err)}}()panic("hello, panic!")
}

嵌套崩溃

嵌套崩溃是指在一个 goroutine 中调用 panic() 函数,然后在 defer 语句中再次调用 panic() 函数。在这种情况下,panic() 函数会从内向外传播,直到程序崩溃。嵌套崩溃可能会导致程序不可用,因此应避免使用。

func multiplePanic() {defer fmt.Println("in defer")defer func() {defer func() {panic("panic 3")}()panic("panic 2")}()panic("panic 1")
}

相关文章:

  • C //练习 4-9 以上介绍的getch与ungetch函数不能正确地处理压回的EOF。考虑压回EOF时应该如何处理?请实现你的设计方案。
  • 国内有哪些比较好用的低代码开发平台?JNPF算一个
  • 深入Pandas(二):高级数据处理技巧
  • Java 常见缓存详解以及解决方案
  • 硬盘检测软件 SMART Utility mac功能特色
  • web第一次作业
  • 如何在OpenWRT部署uhttpd搭建服务器实现远程访问本地web站点
  • 超维空间M1无人机使用说明书——41、ROS无人机使用yolo进行物体识别
  • 【JAVA基础】JVM之类加载--双亲委派机制
  • C语言——结构体类型(二)【结构体内存对齐,结构体数组】
  • 美客多本土店与跨境店有何区别?本土店如何入驻运营?
  • IPv6邻居发现协议(NDP)---路由发现
  • Web缓存代理
  • 【算法】七夕祭
  • What does `$?` do?
  • Angular数据绑定机制
  • Git 使用集
  • golang中接口赋值与方法集
  • JavaScript实现分页效果
  • Js基础知识(一) - 变量
  • JS题目及答案整理
  • js中的正则表达式入门
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 多线程 start 和 run 方法到底有什么区别?
  • 关于for循环的简单归纳
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 思考 CSS 架构
  • 线上 python http server profile 实践
  • 再谈express与koa的对比
  • 找一份好的前端工作,起点很重要
  • 《天龙八部3D》Unity技术方案揭秘
  • # .NET Framework中使用命名管道进行进程间通信
  • #if和#ifdef区别
  • #LLM入门|Prompt#3.3_存储_Memory
  • (31)对象的克隆
  • (NSDate) 时间 (time )比较
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (南京观海微电子)——I3C协议介绍
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (一) springboot详细介绍
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)程序员疫苗:代码注入
  • ./configure、make、make install 命令
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例