深入理解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


相关推荐: 浅谈javascript alert和confirm的美化  如何在景安服务器上快速搭建个人网站?  黑客如何通过漏洞一步步攻陷网站服务器?  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  Python结构化数据采集_字段抽取解析【教程】  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Python进程池调度策略_任务分发说明【指导】  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何在阿里云ECS服务器部署织梦CMS网站?  浅谈Javascript中的Label语句  深圳网站制作的公司有哪些,dido官方网站?  怎么用AI帮你为初创公司进行市场定位分析?  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  如何用花生壳三步快速搭建专属网站?  Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置  如何选择PHP开源工具快速搭建网站?  移动端脚本框架Hammer.js  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  如何在景安云服务器上绑定域名并配置虚拟主机?  Laravel中的Facade(门面)到底是什么原理  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  中国移动官方网站首页入口 中国移动官网网页登录  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  Python面向对象测试方法_mock解析【教程】  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  如何在Windows虚拟主机上快速搭建网站?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  制作电商网页,电商供应链怎么做?  如何在Windows服务器上快速搭建网站?  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  如何用美橙互联一键搭建多站合一网站?  Laravel Docker环境搭建教程_Laravel Sail使用指南  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  JS去除重复并统计数量的实现方法  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  C++用Dijkstra(迪杰斯特拉)算法求最短路径  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  如何自定义建站之星网站的导航菜单样式?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  Laravel路由怎么定义_Laravel核心路由系统完全入门指南