深入理解golang的异常处理机制

发布时间 - 2026-01-11 02:24:13    点击率:

前言

众所周知在java或php等很多面向对象的语言中, 异常处理是依靠throw、catch来进行的。在go语言中,panic和recover函数在作用层面分别对等throw和catch语句,当然也存在不同之处。下面话不多说,来一起看看详细的介绍吧。

从设计层面来看,panic和recover函数适用于那些真正的异常(例如整数除0),而throw catch finally机制常常被用来处理一些业务层面的自定义异常。因此在go语言中,panic和recover要慎用。

上述两种异常机制的使用中,在处理异常时控制流程的走向也是相似的。

下面将分别举例说明:

try catch finally机制

 try{
 throw new Exception();
 } catch(Exception $e) {
 do something ...
 } finally {
 
 }

这种机制中,我们把可能抛出异常的语句或抛出自定义异常的语句放置到try语句块中,而在catch块中,我们将上述语句抛出的异常捕获,针对不同的异常进行报警或log等处理。之后,控制流程进入到finally语句块中。若没有finally语句,控制流程将进入到catch之后的语句中。也就是说,在这种机制中,控制流程是转移到同一层级中异常捕获之后的语句中。

panic recover defer机制

在go的异常机制中,panic可以将原有的控制流程中断,进入到一个"恐慌"流程。这种恐慌流程可以显式调用panic()函数产生或者由运行时错误产生(例如访问越界的数组下标)。panic会在调用它的函数中向本层和它的所有上层逐级抛出,若一直没有recover将其捕获,程序退出后会产生crash;若在某层defer语句中被recover捕获,控制流程将进入到recover之后的语句中。

 /* example 1 */
 package main
 import (
 "fmt"
 )

 func f() {
 defer func() {
  fmt.Println("b")
  if err := recover();err != nil {
  fmt.Println(err)
  }
  fmt.Println("d")
 }()
 fmt.Println("a")
 panic("a bug occur")
 fmt.Println("c")
 }

 func main() {
 f()
 fmt.Println("x")
 }

在上述举例中,输出结果为:

 a
 b
 a bug occur
 d
 x

这说明,在f函数中抛出的panic被自己defer语句中的recover捕获,然后控制流程进入到recover之后的语句中,即打印d、打印x,之后进程正常退出。

 /* example 2 */
 package main
 import (
  "fmt"
 )

 func g() {
  defer func() {
   fmt.Println("b")
   if err := recover();err != nil {
    fmt.Println(err)
   }
   fmt.Println("d")
  }()
  f()
  fmt.Println("e")
 }

 func f() {
  fmt.Println("a")
  panic("a bug occur")
  fmt.Println("c")
 }

 func main() {
  g()
  fmt.Println("x")
 }

上述案例的输出结果是:

 a
 b
 a bug occur
 d
 x

进程经历了这样一个过程:f()中抛出panic,由于自身没有定义defer语句,panic被抛到g()中。g()的defer语句中定义了recover,捕获panic后并执行完defer剩余的语句,之后控制流程被转交到main()函数中,直至进程结束。

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# golang  # 异常处理  # 教程  # Go语言异常处理(Panic和recovering)用法详解  # Golang中异常处理机制详解  # 小学生也能看懂的Golang异常处理recover panic  # Go语言中更优雅的错误处理  # Go 错误处理实践总结示例  # Golang错误处理:异常捕捉和恢复机制  # 抛出  # 自定义  # 两种  # 而在  # 适用于  # 会在  # 将其  # 在这种  # 这样一个  # 这篇文章  # 一直没有  # 谢谢大家  # 多说  # 后会  # 众所周知  # 面向对象  # 将原  # 不同之处  # 举例说明  # 中向 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器如何优化才能显著提升网站加载速度?  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  装修招标网站设计制作流程,装修招标流程?  如何快速上传建站程序避免常见错误?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  EditPlus中的正则表达式 实战(2)  如何制作一个表白网站视频,关于勇敢表白的小标题?  html如何与html链接_实现多个HTML页面互相链接【互相】  HTML 中动态设置元素 name 属性的正确语法详解  利用vue写todolist单页应用  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  Laravel Docker环境搭建教程_Laravel Sail使用指南  Laravel怎么导出Excel文件_Laravel Excel插件使用教程  制作旅游网站html,怎样注册旅游网站?  Laravel模型事件有哪些_Laravel Model Event生命周期详解  5种Android数据存储方式汇总  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  如何快速建站并高效导出源代码?  软银砸40亿美元收购DigitalBridge 强化AI资料中心布局  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  大型企业网站制作流程,做网站需要注册公司吗?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  手机软键盘弹出时影响布局的解决方法  Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧  如何快速搭建支持数据库操作的智能建站平台?  如何自定义建站之星模板颜色并下载新样式?  Laravel如何实现文件上传和存储?(本地与S3配置)  Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  Firefox Developer Edition开发者版本入口  如何在阿里云完成域名注册与建站?  如何快速使用云服务器搭建个人网站?  iOS验证手机号的正则表达式  浅谈javascript alert和confirm的美化  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Laravel如何使用模型观察者?(Observer代码示例)  网站建设要注意的标准 促进网站用户好感度!  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  如何快速登录WAP自助建站平台?  Android使用GridView实现日历的简单功能  使用Dockerfile构建java web环境  如何用JavaScript实现文本编辑器_光标和选区怎么处理  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  jQuery中的100个技巧汇总  Bootstrap整体框架之JavaScript插件架构  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】