go语言的异常处理机制

error

在go语言中,异常被定义为实现了error接口的类型,error接口只定义了一个返回string类型Error()方法,任何实现了Error()方法的类型都可以被定义为异常,以下是一个自定义的异常类型:
 

type MyError struct {
	data   string
	errNO  int
	errMsg string
}
// 定义错误方法
func (err *MyError) Error() string {
	return err.errMsg
}

如果我们直接打印一个error对象,实际上调用的是error.Error()

panic

在通常情况下,向程序使用方报告错误状态的方式可以是返回一个额外的error类型值。

但是,当遇到不可恢复的错误状态的时候,如数组访问越界、空指针引用等,这些运行时错误会引起painc异常。这时,上述错误处理方式显然就不适合了。反过来讲,在一般情况下,我们不应通过调用panic函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。当某些不应该发生的场景发生时,我们就应该调用panic。

一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程,在中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。

不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常;panic函数接受任何值作为参数。

异常的捕获recover

在Go语言中,异常可以通过recover()函数来捕获。recover()函数必须在defer语句中调用,用于捕获当前函数调用栈中的异常。如果当前函数中没有异常,recover()函数将返回nil

以下是一个使用recover()函数捕获异常的示例:

func DoSomething() error {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println(r)
        }
    }()
    if someError {
        panic(&MyException{"something went wrong"})
    }
    return nil
}
package main

import "fmt"

//type error interface {
//	Error() string
//}

// 自定义错误返回类型
type MyError struct {
	data   string
	errNO  int
	errMsg string
}

var defaultCode = 200

// 定义错误方法
func (err *MyError) Error() string {
	return err.errMsg
}

// 定义两种不同的方法返回函数
func defaultError(msg string) error {
	return &MyError{errMsg: msg, errNO: defaultCode}
}
func initError(msg string, errno int) error {
	return &MyError{errMsg: msg, errNO: errno}
}
func div(y int) int {
	var x = 10
	z := x / y
	fmt.Println(z)
	return z

}
func do() {

}
func main() {

	defer func() {
		if e := recover(); e != nil {
			err := initError("sda", 232)
			fmt.Println(err)
		}
	}()
	div(0)

}

在上面的示例中,我们在DoSomething()函数中使用了defer语句,在函数返回之前将一个匿名函数压入调用栈。这个匿名函数中使用了recover()函数来捕获异常。如果异常被捕获,就会输出异常信息,否则这个函数什么也不会做。

panicrecover的实现原理

在Go语言中,panicrecover语句的实现原理比较复杂。下面将介绍这些语句的实现原理。

  • panic的实现原理

当程序执行到panic函数时,它会停止当前的执行流程,并且开始执行所有被注册的defer语句。然后,程序会停止执行,并且将控制权交给调用栈中的上一级函数。如果调用栈中的任何函数都没有捕获这个异常,程序将会崩溃并且打印出错误信息。

在底层实现中,panic函数会创建一个panic结构体,并且将该结构体的指针保存在当前的goroutine结构体中。然后,panic函数会继续执行所有被注册的defer语句,直到所有的defer语句都执行完毕。最后,panic函数会停止执行,并且将控制权交给调用栈中的上一级函数。

  • recover的实现原理

当程序执行到recover函数时,它会检查当前的goroutine结构体中是否存在一个panic结构体的指针。如果存在,recover函数会返回该panic结构体的值,并且清除该结构体的指针。然后,程序会继续执行。

在底层实现中,recover函数会检查当前的goroutine结构体中是否存在一个panic结构体的指针。如果存在,recover函数会返回该panic结构体的值,并且清除该结构体的指针。如果不存在,recover函数会返回nil

异常处理的最佳实践

在Go语言中,异常处理是非常重要的,它可以帮助我们诊断程序中的错误,并提供一种优雅的方式来处理这些错误。以下是一些处理异常的最佳实践:

  1. 不要滥用异常

异常应该只用于处理真正的异常情况,例如不可恢复的错误、硬件故障等。不要滥用异常,将其作为一种流程控制的手段来使用。

2. 在需要的地方抛出异常

只有在必要的时候才应该抛出异常,例如当出现无法恢复的错误或者不符合预期的行为时。不要在可以通过其他方式解决的问题上抛出异常。

3. 在需要的地方捕获异常

只有在需要的时候才应该捕获异常。在不需要处理异常的情况下,不要捕获异常。在必要的时候,尽可能早地捕获异常,以避免异常在代码中蔓延。

4. 在捕获异常时提供上下文信息

当捕获异常时,应该提供足够的上下文信息,以便于快速定位和解决问题。例如,在异常信息中包含发生异常的函数、文件名、行号等信息,可以帮助我们快速定位问题所在。

5. 不要忽略异常

不要忽略任何异常,无论是自己抛出的还是调用库函数时捕获的异常。忽略异常会导致程序的行为不可预期,可能会导致严重的后果。

总结

Go语言异常机制是一种非常重要的特性,它可以帮助我们诊断程序中的错误,并提供一种优雅的方式来处理这些错误。在使用异常时,需要注意不要滥用异常,只在必要的时候抛出异常和捕获异常,提供足够的上下文信息,并且不要忽略任何异常。如果合理使用异常,可以让我们的代码更加健壮、清晰和可读。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【零基础】学JS

喝下这碗鸡汤 “知识就是力量。” - 弗朗西斯培根 1.三元运算符 目标:能利用三元运算符执行满足条件的语句 使用场景:其实是比if双分支更简单的写法,可以使用三元表达式 语法:条件 ? 满足条件的执行代码 : 不满足条件执行的代码 接下来用一个小案例来展…

昇思25天学习打卡营第十四天|Pix2Pix实现图像转换

训练营进入第十四天,今天学的内容是Pix2Pix图像转换,记录一下学习内容: Pix2Pix概述 Pix2Pix是基于条件生成对抗网络(cGAN, Condition Generative Adversarial Networks )实现的一种深度学习图像转换模型&#xff0c…

读书笔记-《魔鬼经济学》

这是一本非常有意思的经济学启蒙书,作者探讨了许多问题,并通过数据找到答案。 我们先来看看作者眼中的“魔鬼经济学”是什么,再选一个贴近我们生活的例子进行阐述。 01 魔鬼经济学 中心思想:假如道德代表人类对世界运转方式的期…

Vue 3集成krpano 全景图展示

Vue 3集成krpano 全景图展示 星光云全景系统源码 VR全景体验地址 星光云全景VR系统 将全景krpano静态资源文件vtour放入vue项目中 导入vue之前需要自己制作一个全景图 需要借助官方工具进行制作 工具下载地址:krpano工具下载地址 注意事项:vuecli…

LRU缓存算法设计

LRU 缓存算法的核⼼数据结构就是哈希链表,双向链表和哈希表的结合体。这个数据结构⻓这样: 创建的需要有两个方法,一个是get方法,一个是put方法。 一些问题:为什么需要使用双向链表呢?因为删除链表的本身&…

2-26 基于matlab开发的制冷循环模型

基于matlab开发的制冷循环模型。Simscape两相流域中的制冷循环模型,在simulink中完成多循环温度控制。程序已调通,可直接运行。 2-26 制冷循环模型 Simscape两相流域 - 小红书 (xiaohongshu.com)

Web3D引擎,three.js堪称扛把子,Babylon.js差点意思。

涉及到Web3D开发,Three.js和Babylon.js是两个备受推崇的引擎。它们都是基于WebGL的开源3D引擎,用于创建交互式的3D图形应用程序,但要细论起来,three.js普及度远超Babylon .js. 一、二者的介绍 Three.js: Three.js 是一…

Android仿今日头条新闻(一)

新建一个侧边栏的文件,创建成功后直接运行。可以看到带滑动的侧边栏功能如图所示: 主体UI: 新闻UI的实现: 侧边栏: 更换一下颜色: 学习参考-浩宇开发

Objects365数据集介绍

Objects365数据集介绍 什么是Objects365数据集?数据集的规模与内容数据集的特点数据集下载 什么是Objects365数据集? Objects365是一个大规模、高质量的物体检测数据集。该数据集旨在推动物体检测技术的发展,特别是在真实世界场景下的应用。O…

STM32-01 推挽输出-点亮LED

本文以STM32中点亮LED为例,解读推挽输出的原理 推挽输出介绍 所谓的推挽输出,就是通过控制输出控制模块,打开或者关闭P-MOS或者N-MOS。 ─ 推挽模式下:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-M…

尚品汇-(十三)

&#xff08;1&#xff09;查询sku列表 在ManageService 中添加 /*** SKU分页列表* param pageParam* return*/ IPage<SkuInfo> getPage(Page<SkuInfo> pageParam);接口实现类 Override public IPage<SkuInfo> getPage(Page<SkuInfo> pageParam) {Qu…

【双一流高校主办,Springer-LNICST出版,EI稳定检索】2024年应用计算智能、信息学与大数据国际会议(ACIIBD 2024,7月26-28)

2024年应用计算智能、信息学与大数据国际学术会议&#xff08;ACIIBD 2024&#xff09;将于2024年7月26-28日在中国广州举办。会议将聚焦于计算智能及其应用、信息、大数据等相关的研究领域&#xff0c; 广泛邀请国内外知名专家学者&#xff0c;共同探讨相关学科领域的最新发展…

Ubuntu + SSH密钥连接服务器

1. 下载VS code cd到下载文件夹后&#xff0c;使用命令安装&#xff0c;把xxx复制为文件名 sudo dpkg -i xxx.deb2. 为VSCode换皮肤 3. 下载SSH插件和Docker插件 4. 配置SSH 把密钥key文件放在/home/your_user_name/.ssh/里面&#xff0c;然后在/home/your_user_name/.ssh/c…

第1集《修习止观坐禅法要》

《修习止观坐禅法要》诸位法师&#xff0c;诸位学员&#xff0c;阿弥院佛&#xff01; 我们今天能够暂时放下世间的尘劳&#xff0c;大家在一起研究佛法的课程&#xff0c;这件事情在我们的生命当中是非常的稀有难得。 基本上&#xff0c;我们佛法的修习目的是追求身心的安乐…

基于vue的3D高德地图的引入

在引入高德地图的时候需要先注册一个账号 登录下面的网站 账号认证 | 高德控制台 (amap.com) 打开首页应用管理&#xff0c;我的应用 创建新的应用 根据自己的需求进行选择 创建完成之后&#xff0c;点击添加key 不同的服务平台对应不同的可使用服务&#xff0c;选择自己适…

3.js - 模板渲染 - 金属切面效果

md&#xff0c;狗不学&#xff0c;我学 源码 // ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.m…

机器学习与深度学习:区别(含工作站硬件推荐)

一、机器学习与深度学习区别 机器学习&#xff08;ML&#xff1a;Machine Learning&#xff09;与深度学习&#xff08;DL&#xff1a;Deep Learning&#xff09;是人工智能&#xff08;AI&#xff09;领域内两个重要但不同的技术。它们在定义、数据依赖性以及硬件依赖性等方面…

如何在忘记密码的情况下解锁Android手机?

您的 Android 设备密码有助于保护您的数据并防止您的个人信息被滥用。但是&#xff0c;如果您被锁定在Android设备之外怎么办&#xff1f;我们知道忘记您的 Android 手机密码是多么令人沮丧&#xff0c;因为它会导致您的设备和数据无法访问。在本技术指南中&#xff0c;我们将向…

[图解]企业应用架构模式2024新译本讲解23-标识映射2

1 00:00:00,950 --> 00:00:02,890 好&#xff0c;我们往下走 2 00:00:04,140 --> 00:00:04,650 一样的 3 00:00:04,660 --> 00:00:07,170 这前面也见过了&#xff0c;定义一个对象数组 4 00:00:07,870 --> 00:00:12,820 数组的长度就是字段的数量&#xff0c;4个…

学IT上培训班真的有用吗?

在学习IT技术的过程中&#xff0c;你是否也被安利过各种五花八门的技术培训班&#xff1f;这些培训班都是怎样向你宣传的&#xff0c;你又对此抱有着怎样的态度呢&#xff1f;在培训班里学技术&#xff0c;真的有用吗&#xff1f; 一、引入话题 IT行业是一个快速发展和不断变化…