Golang错误处理机制

文章目录

  • Golang错误处理机制
    • panic异常
    • recover捕获异常
    • 自定义错误

Golang错误处理机制

panic异常

panic异常

  • Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,比如除零错误、数组访问越界、空指针引用等,这些运行时错误会引起panic异常。
  • 当panic异常发生时,程序会中断运行,并立即执行当前函数中的defer语句,然后程序会从调用栈中逐级返回,返回同时执行各级函数中的defer语句,直到panic被捕获或程序终止。

例如,下面的代码在运行过程中,由于存在除零错误将导致panic异常。如下:

package mainimport "fmt"func Division(num1 int, num2 int) int {defer fmt.Println("Division defer...")return num1 / num2
}func main() {defer fmt.Println("main defer...")// panic异常result := Division(10, 0)fmt.Printf("result = %d\n", result)fmt.Println("other code...")
}

运行代码后可以看到,main函数中调用Division函数之后的代码没有被执行。但在程序退出之前,Division和main函数中的defer语句被逐一执行。如下:

在这里插入图片描述

recover捕获异常

recover捕获异常

  • 当触发panic异常时,我们希望程序可以继续运行,并希望在触发异常后,能够执行某些操作,比如给管理员发送一条告警信息。
  • 在Go中,捕获异常通过在defer中调用内建函数recover实现,recover函数会使程序从panic中恢复,并返回触发panic的值,如果程序没有发生panic,则recover调用将会返回nil。
  • 需要注意的是,当异常被捕获后,触发panic异常的函数也不会继续运行,但能正常返回。

例如,下面在Division函数的defer中捕获了panic异常,并将触发panic异常的值进行了返回。如下:

package mainimport "fmt"func Division(num1 int, num2 int) (result int, err error) {defer func() {if r := recover(); r != nil {err = r.(error) // 类型断言,将r转换为error类型(后续介绍)}}()return num1 / num2, nil
}func main() {// recover捕获异常result, err := Division(10, 0)if err != nil {fmt.Printf("division operation error, err = %v\n", err)} else {fmt.Printf("result = %d\n", result)}
}

运行代码后可以看到,由于panic异常被捕获使得Division函数正常返回,同时main函数后续的代码也被正常执行。如下:

在这里插入图片描述

由于panic异常会逐级抛出,直到异常被捕获或程序终止,因此可以选择在调用链的任意一个函数中对panic进行捕获。如下:

package mainimport "fmt"func Division(num1 int, num2 int) int {return num1 / num2
}func main() {// recover捕获异常defer func() {if err := recover(); err != nil {fmt.Printf("recoverd from panic, err = %v\n", err)}}()result := Division(10, 0)fmt.Printf("result = %d\n", result)fmt.Println("other code...")
}

由于Division函数中没有对panic进行捕获,导致main函数触发panic异常,虽然在main函数中对panic进行了捕获,但main函数的后续代码将不会被执行。如下:

在这里插入图片描述

自定义错误

自定义错误

  • 不是只有程序在运行时出现错误才能触发panic异常,通过调用内建函数panic也能触发panic异常。
  • panic函数能够接收任何类型的值作为参数,并在触发panic时将其作为触发panic的值。
  • 触发panic的值通常是error类型的,通过errors包中的New函数可以创建一个error类型的错误值,该函数接收一个string类型的参数,并返回创建的error类型的错误值。

例如,我们规定除数不能为20,否则触发panic异常。如下:

package mainimport ("errors""fmt"
)func Division(num1 int, num2 int) (result int, err error) {defer func() {if r := recover(); r != nil {err = r.(error)}}()if num2 == 20 {panic(errors.New("integer divide by 20"))}return num1 / num2, nil
}func main() {// recover捕获异常result, err := Division(10, 20)if err != nil {fmt.Printf("division operation error, err = %v\n", err)} else {fmt.Printf("result = %d\n", result)}
}

运行代码后可以看到,通过panic函数触发的异常也能够成功被捕获。如下:

在这里插入图片描述

说明一下: 通过recover将panic捕获后,可以继续通过调用panic函数将panic再次抛出,使其传播到更高层的调用栈进行进一步处理,这叫做异常的重新抛出。

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

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

相关文章

springboot-异步、定时、邮件任务

目录 一,前言 二,异步 2.1,案例: 1,首先创建一个service: 2,Controller: ① 想办法告诉spring我们的异步方法是异步的,所以要在方法上添加注解 Async ②去springboot主程序中开…

可以在手机端运行的大模型标杆:微软发布第三代Phi-3系列模型,评测结果超过同等参数规模水平,包含三个版本,最小38亿,最高140亿参数

本文原文来自DataLearnerAI官方网站: 可以在手机端运行的大模型标杆:微软发布第三代Phi-3系列模型,评测结果超过同等参数规模水平,包含三个版本,最小38亿,最高140亿参数 | 数据学习者官方网站(Datalearner…

CH4INRULZ-v1靶机练习实践报告

CH4INRULZ-v1靶机练习实践报告 1 安装靶机 靶机是.ova文件,需要用VirtualBox打开,但我习惯于使用VMWare,因此修改靶机文件,使其适用于VMWare打开。 解压ova文件,得到.ovf文件和.vmdk文件。直接用VMWare打开.ovf文件即可。 2 夺…

【Unity动画系统】Animator组件的属性

介绍Animator组件的全部属性 Controller:动画控制器 Avatar:人物骨骼 Apply Root Motion:有一些动画片段自带位移,如果希望自带的位移应用在游戏对象上,那么就勾选;如果自己编写脚本,那么就不…

Xcode 15构建问题

构建时出现的异常: 解决方式: 将ENABLE_USER_SCRIPT_SANDBOXING设为“no”即可!

stm32 hid自定义接收发送程序开发过程记录

cubleMX配置如下 修改端点描述符一次传输的数据大小 根据cubelMX标准在这里修改 编译错误 直接修改(因为没有使用nodef )编译通过 修改报告描述符(默认的描述符无法传输数据) 参考:USB协议详解第10讲(USB描…

Web 渗透测试神器:HackBar 保姆级教程

一、介绍 HackBar 是一个用于浏览器的扩展插件,主要用于进行网络渗透测试和安全评估。它提供了一系列方便的工具和功能,可以帮助用户执行各种网络攻击和测试,包括 XSS、SQL 注入、CSRF、路径穿越等。以下是 HackBar 插件的一些主要特点和功能…

Java使用SpringBoot和EasyExcel 实现动态数据导出实战

Java使用SpringBoot和EasyExcel 实现动态数据导出实战 1、前言2、【资源地址】3、代码示例(demo)4、目前Java实现数据导出为Excel方式5、依赖6、总结 1、前言 工作中有用到将数据导出为Excel的场景,在此记录下。在日常开发中,Excel文件处理是一项常见的…

【VSCode调试技巧】Pytorch分布式训练调试

最近遇到个头疼的问题,对于单机多卡的训练脚本,不知道如何使用VSCode进行Debug。 解决方案: 1、找到控制分布式训练的启动脚本,在自己的虚拟环境的/lib/python3.9/site-packages/torch/distributed/launch.py中 2、配置launch.…

【网络安全】HTTP协议 — 基础

专栏文章索引:网络安全 有问题可私聊:QQ:3375119339 目录 学习目标​ 一、万维网的诞生与发展​编辑 1.万维网的诞生与发展 2.HTTP协议诞生与发展 二、网络基础 1.TCP/IP分层传输 1)TCP/IP协议 2)封装与拆封 …

[二叉树] 二叉树的前中后三序遍历#知二求一

标题:[二叉树] 二叉树的前中后三序遍历#知二求一 水墨不写bug (图片来源于网络) 正文开始: 其实这一类题就是考察对二叉树的结构理解,此类题目的二叉树一般通过数组传入,我们只需根据二叉树的就够特点对数…

用例整体执行及pytest.ini文件

在我们写代码的过程中,一般都是右键或者命令行去执行一个用例 但是当我们写完后,需要整体执行一遍。那应该怎么搞呢? 我们可以在根目录下新建一个main.py或者run.py之类的文件,文件内容如下: if __name__ "__ma…

设计模式 基本认识

文章目录 设计模式的作用设计模式三原则设计模式与类图设计模式的分类 设计模式的作用 设计模式是在软件设计过程中针对常见问题的解决方案的一种通用、可重用的解决方案。设计模式提供了一种经过验证的方法,可以帮助开发人员解决特定类型的问题,并在软…

社区新零售:重构邻里生活圈,赋能美好未来

新时代的邻里脉动 在城市的肌理中,社区作为生活的基本单元,正经历一场由新零售引领的深刻变革。社区新零售,以其独特的商业模式、创新的技术手段和以人为本的服务理念,重新定义了社区商业的边界,重构了邻里生活的形态…

CANoe中周期事件报文的配置方法

方法记录,最近在配置测试环境时遇到了如下的问题: Q:在通信矩阵中该报文应该为CE型报文。但是在DBC中设置模式为CE型时就无法发送,trace中不会出现此报文,将它设置为周期型报文,就能正常在trace中出现。 A:DBC中不能…

安装ROS

前提必须是20.04版本。。。 一、首先,先设置安装源,我们选择国内中科大的安装源 sudo sh -c . /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ lsb_release -cs main" > /etc/apt/sources.list.d/ros-lat…

便携式iv检测仪解析

TH-PV31光伏电站便携式IV功率测试仪是一种专门用于光伏电站运维和故障排查的设备。它具备高精度、快速测试以及便携性等特点,成为光伏电站日常运维中不可或缺的工具。 首先,从工作原理来看,光伏电站便携式IV功率测试仪通过模拟太阳光照射光伏…

.NET C# ORM 瀚高数据库

SqlSugar ORM SqlSugar 是一款 老牌 .NET开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用最易上手的ORM 优点 :【生态丰富】【高性能】【超简单】 【功能全面】 【多库兼容】【适合产品】 【SqlSugar视频教程】 支持 &#xff1a…

go版本1.16.5 运行项目出现undefined: math.MaxInt报错

问题描述 go版本 go1.16.5 项目引用了 包go-sqlite3 v1.14.17 github.com/mattn/go-sqlite3 v1.14.17运行报错 # github.com/mattn/go-sqlite3 D:\GoPATH\pkg\mod\github.com\mattn\go-sqlite3v1.14.17\sqlite3_opt_serialize.go:41:26: undefined: math.MaxInt原因分析&…

行为型设计模式

一、责任链设计模式 (一)概念 使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 (二&#xf…