Golang异常处理机制

 go语言使用error来处理错误,用panic和recover来处理异常

error

go语言的错误处理有两个发展阶段,以go1.13版本为分水岭,在1.13版本之前,标准库对error的支持非常有限,仅有errors.New()和fmt.Errorf()两个函数来构造errorString实例。在这个阶段,error处理存在一个非常大的问题:传递错误时,使用fmt.Errorf()传递捕获的error并为error增加上下文信息时,原error将和上下文的描述信息混杂在一起,导致原始的error信息丢失。

在go1.13版本,Go官方加强了对errors的支持,在进行错误传递的时候,采用链式传递的方式,将同一上下文的error链接起来,并且保留原始的error信息。通过在fmt.Errorf()中增加一个格式动词%w,来创建链式的error,并且提供errors.Unwarp()来拆解error。

创建错误的两种方式:

  1. errors.New(str string)

  2. fmt.Errorf("format string",a ...any)

我们可以通过以上两种方式来创建错误类型,第一种创建出来的是stringError,第二种方式创建出来的类型,取决于传入的格式动词,在1.13版本之前只能够创建stringError类型的错误。在1.13版本之后,通过传入格式动词%w,可以创建出warpError类型的错误,我们需要注意的是,传入的%w应该和传入的err来配对。

defer

不仅函数正常返回会执行被defer延迟的函数,函数中任意一个return语句、panic语句均会触发延迟函数。

defer的三大规则:

  1. 延迟函数的参数在defer语句出现时就已经确定了,延迟函数体中引用的变量,在编译的会绑定主函数中的对应变量,会获取变量的最终值。【对于指针函数的变量,复制的是地址值】

  2. 延迟函数按后进先出的顺序执行,即先出现的defer最后执行

  3. 延迟函数可能会操作主函数的具名返回值。【return的返回操作并不是原子性的,而是分为两个步骤:一是设置返回值,二是执行跳转,defer语句发生在跳转之前】(分析方向,先判断返回值的类型,是匿名还是具名,只有在defer语句中,对具名返回值进行更改的时候,才会修改返回值)

panic

panic的工作机制:每一个协程中都维护一个defer链表,执行过程中每遇到一个defer语句都会创建一个defer实例,并将这一个defer实例插入链表,函数退出时取出本函数创建的defer实例并执行。panic发生时,实际上是把程序的流程转向了这一个defer链表,程序专注于消费链表中的defer函数,当链表中的defer函数被消费完,再触发程序的退出。

我们在程序中一些可以预料到的、业务上的错误,可以通过定义err进行异常处理,处理err时,我们的程序是正常的,按照我们编写的逻辑顺序执行的。 而panic则用来处理不可预料到的错误和进行危险操作时触发panic。一旦程序发生panic,那么panic所在的函数体之后的代码将不会再执行,转而递归执行当前协程所有的defer函数,当前协程中的所有defer处理完成后,触发程序退出。如果panic执行过程中任意一个defer函数执行了recover(),那么panic的处理流程就会中止。程序继续执行上游函数中的代码。

recover

内置函数recover()用于消除panic并使程序回到正常的执行流程中。

recover的返回值是捕获到的panic()函数的参数

recover()执行之后,程序的执行流程转向上游函数,并且上游函数感知不到panic的发生。而发生panic的函数后面的代码不会被执行。【一旦发生惊慌,函数的执行流程就变了】

recover()函数必须直接位于defer函数中才有效。defer func() { recover() }()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaweb中的请求与响应--基于postman工具的应用(附带postman的详细安装步骤)

一、前言 后端的第一天感觉难度就上来了,可能是基础太过薄弱了吧。目前看视频已经有点跟不上了,果然15天想要拿下还是太勉强了点。30天还差不多。不知道读者们有没有好好的去学这方面的知识,没有什么是学不会的,关键是坚持。 Po…

几个小创新模型,KAN组合网络(LSTM、GRU、Transformer)回归预测,python预测全家桶再更新!...

截止到本期,一共发了9篇关于机器学习预测全家桶Python代码的文章。参考往期文章如下: 1.终于来了!python机器学习预测全家桶 2.机器学习预测全家桶-Python,一次性搞定多/单特征输入,多/单步预测!最强模板&a…

萝卜快跑的狠活

萝卜快跑作为百度旗下的自动驾驶出行服务平台,在科技应用上展现了多项领先的技术。以下是萝卜快跑采用的一些主要科技“狠活”: 自动驾驶技术: 萝卜快跑主要使用了百度Apollo的L4级自动驾驶技术,该技术能够应对海量的城市道路场景…

C++:重定义

派生类和基类的同名成员问题 派生类中再实现一个基类中的方法会怎样 (1)代码实验:派生类和基类中各自实现一个内容不同但函数原型完全相同的方法,会怎么样 (2)结论:基类对象调用的是基类的方法,派生类对象调用执行的是派生类中重…

进程调度篇

在操作系统的广阔领域中,进程调度是其中一个至关重要的环节。它如同操作系统的“交通警察”,负责在多个等待CPU执行的进程间进行高效、公平的分配。本文将带您了解进程调度的基本概念、重要性、常用算法…… 1. 进程调度的基本概念 1.1 进程调度的定义 …

【FreeRTOS】freeRTOS的Tmr Svc任务优先级配置

1、Tmr Svc是个FreeRTOS的软件定时器任务,他可以收集各任务的状态 2、他的优先级可以通过宏 configTIMER_TASK_PRIORITY 来配置,默认是2 3、修改为31后,程序总是启动不了, 4、后面才发现原来FreeRTOS的默认最大优先级号配置的是…

工具指南 - jenkins

一、接入SonarQube 扫描代码 SonarQube是一个用于管理代码质量的开放平台,可以快速的定位代码中潜在的或者明显的错误。 1.1 源码管理 如果源码托管在SVN,需要进行Subversion配置: Repository URL:源码地址,比如https:…

一键优雅为Ubuntu20.04服务器挂载新磁盘

itopen组织1、提供OpenHarmony优雅实用的小工具2、手把手适配riscv qemu linux的三方库移植3、未来计划riscv qemu ohos的三方库移植 小程序开发4、一切拥抱开源,拥抱国产化 一、小于2T磁盘挂载方式 1.1 安装磁盘到电脑后启动系统 1.2 查找未分区的磁盘 打…

ios swift5 蓝牙广播出数据

WARNING: The advertisement key ‘Manufacturer Data’ is not allowed WARNING: The advertisement key ‘Service Data’ is not allowed manager?.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [myService?.uuid], CBAdvertisementDataLocalNameKey : "…

鸿蒙Navigation的页面跳转官方代码

星河版本 文章部分代码来源于官方 文章部分代码来源于官方只是自己改了容易理解 与API4不同的Navigation 新版本使用的思路是 1、创建页面栈 pageInfos: NavPathStack new NavPathStack();2、resources/base/profile创建 router_map.json 文件 {"routerMap":…

数电设计提问求帮助,出租车计费器。

🏆本文收录于《CSDN问答解惑-》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&…

Autosar诊断实战系列28-2E写DID Pending期间偶发回NRC0x13问题排查

本文框架 前言1.问题描述2.问题复现3.问题分析问题1:为何在2E Pending期间会发送功能寻址的10 01回NRC13?问题2:在ECU Pending期间收到功能寻址10 01,MCU需要如何处理?问题3:DcmDslConnection是如何定义的?问题4:功能寻址于物理寻址是否对应不同的DcmDslConnection?问…

Pandas数据可视化宝典:解锁图形绘制与样式自定义的奥秘

Pandas数据可视化宝典:解锁图形绘制与样式自定义的奥秘 引言 数据可视化是将数据以图形或图像的形式展示出来,使复杂的数据更容易被人类理解和分析。在数据分析、商业智能、科学研究等领域,数据可视化都扮演着至关重要的角色。Pandas作为一…

如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?

目录 一、用到的知识点 二、代码展示(分解版) 三、代码展示(整体版) 一、用到的知识点 1.IO流: Input:输入,通过“输入流”进行文件的读取操作 Output:输出,通过“输出流”进行文件的写入操作 2.文件操作相关: File类&#xff…

Point Cloud Library (PCL) for Python - pclpy 安装指南 (2)

Point Cloud Library (PCL) for Python - pclpy 安装指南 (1) 导入库 from pclpy import pcl import numpy as np导入pclpy库中的pcl模块,用于处理点云数据。numpy库用于处理数值数据。 读取点云 cloud pcl.PointCloud.PointXYZRGB() pcl.io.loadPCDFile(F:\\bunn…

2024年西安铁一中集训DAY1---- 杂题选讲

文章目录 牛客练习赛125 E 联谊活动(枚举,分讨)牛客练习赛125 F 玻璃弹珠(类莫队,离线询问,数据结构)2024ccpc长春邀请赛 D Parallel Lines(随机化)2024ccpc长春邀请赛 E…

STM32智能健康监测系统教程

目录 引言环境准备智能健康监测系统基础代码实现:实现智能健康监测系统 4.1 数据采集模块 4.2 数据处理与分析模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景:健康监测与优化问题解决方案与优化收尾与总结 1. 引言 智能健康监测系统通…

k8s 容器环境下的镜像如何转换为docker 使用

在无法连接registry 的环境中,想要把 crictl 中的镜像给docker 使用,应该怎么处理? 其实容器镜像是通用的,crictl 和ctr 以及docker 镜像是可以互相使用的,因为docker 在1.10版本之后遵从了OCI。所以crictl 环境下的镜…

Android Studio 的Gradle下载慢,Gradle切换下载源

看图 下面的文字地址因为转义符号的问题,https后面少了一个斜杠看图片进行补充,直接复制不知道能不能用 distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-8.7-bin.zip

浪潮服务器内存物理插槽位置

浪潮服务器内存物理插槽位置 如下图所示