Go语言 异常panic和恢复recover用法

Go语言 异常panic和恢复recover用法

背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常。在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,才使用Go中引入的Exception处理:defer, panic, recover。

panic:

1、内建函数

2、假如函数F中书写了panic语句,会终止其后要执行的代码,在panic所在函数F内如果存在要执行的defer函数列表,按照defer的逆序执行

比如panic函数内有:

defer   函数1

defer   函数2

defer   函数3

那么执行顺序就是:

函数3

函数2

函数1

3、返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defer的逆序执行,这里的defer 有点类似 try-catch-finally 中的 finally

4、直到goroutine整个退出,并报告错误

recover:

1、内建函数

2、用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为

3、一般的调用建议

a). 在defer函数中,通过recever来终止一个gojroutine的panicking过程,从而恢复正常代码的执行

b). 可以获取通过panic传递的error

简单来讲:go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。

示例代码  main函数相当于调用者G,f函数相当于函数F

func main() {
      fmt.Println("c")
   defer func() { // 必须要先声明defer,否则不能捕获到panic异常
      fmt.Println("d")
      if err := recover(); err != nil {
         fmt.Println(err) // 这里的err其实就是panic传入的内容
      }
      fmt.Println("e")
   }()
   f() //开始调用f
   fmt.Println("f") //这里开始下面代码不会再执行
}

func f() {
   fmt.Println("a")
   panic("异常信息")
   fmt.Println("b") //这里开始下面代码不会再执行
}
-------output-------
c
a
d
异常信息
e

  

注意:利用recover处理panic指令,defer必须在panic之前声明,否则当panic时,recover无法捕获到panic.

原文地址:https://www.cnblogs.com/haiguixiansheng/p/10734844.html

时间: 2024-08-04 02:09:16

Go语言 异常panic和恢复recover用法的相关文章

Go语言圣经-Panic异常,Recover捕获异常习题

Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常:panic函数接受任何值作为参数.3.由于panic会引起程序的崩溃,因此panic一般用于严重错误,如程序内部的逻辑不一致,对于大部分漏洞,我们应该使用Go提供的错误机制,而不是panic4.为了方便诊断问题,runtime包允许输出堆栈信息 Go语言圣经-Reco

Go语言中异常处理painc()和recover()的用法

Go语言中异常处理painc()和recover()的用法 1.Painc用法是:用于抛出错误.Recover()用法是:将Recover()写在defer中,并且在可能发生panic的地方之前,先调用此defer的东西(让系统方法域结束时,有代码要执行.)当程序遇到panic的时候(当然,也可以正常的调用出现的异常情况),系统将跳过后面的代码,进入defer,如果defer函数中recover(),则返回捕获到的panic的值. 2.代码: package main import "fmt&q

用Go语言异常机制模拟TryCatch异常捕捉

有的同学看到Go和TryCatch一起出现,心里可能会说,难道Go语言升级了,加入了try...catch语句.哈哈,其实Go语言从创建之初就没打算加入try...catch语句,因为创建Go的那帮大爷认为try...catch挺烦人的,如果滥用,会造成程序混乱,所以就不打算加入try...catch(以后加不加入不好说). 既然Go语言中并没有try...catch语句,那么为何文章标题说要使用TryCatch呢?其实Go语言中只是没有try...catch语句,并不是没有异常处理机制.Go语

【公告】博客数据异常已全部恢复

亲爱的CSDN博主们, 大家好,由于23日晚上-24日凌晨的博客进行了博客服务器维护,造成了用户访问量.积分和排名的异常情况,截至此刻已全部修复,望相互转告.给大家带来的不便深感抱歉,同时也感谢大家对CSDN的理解与支持~ 如有问题请及时联系客服: 客服微博:@CSDN产品客服 客服QQ:2355263776 客服邮箱:[email protected] 我们将在第一时间为您解决,再次感谢您的支持和理解~ [公告]博客数据异常已全部恢复,码迷,mamicode.com

C语言中关于scanf函数的用法

scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息.可以读入任何固有类型的数据并自动把数值变换成适当的机内格式. 其调用格式为: scanf("<格式化字符串>",<地址表>); scanf()函数返回成功赋值的数据项数,出错时则返回EOF. 其控制串由三类字符构成

C语言异常与断言接口与实现

程序中通常会出现三种错误:用户错误.运行期错误以及异常 标准库函数setjmp和longjmp 在C语言中,标准库函数setjmp和longjmp形成了结构化异常工具的基础.简单的说就是setjmp实例化处理程序,而longjmp产生异常 setjmp和longjmp是C语言所独有的,它们部分弥补了C语言有限的转移能力.与刺激的abort()和exit()相比,goto语句看起来是处理异常的更可行方案.不幸的是,goto是本地的:它只能跳到所在函数内部的标号上,而不能将控制权转移到所在程序的任意

C语言qsort和C++sort的用法小结和区别比较

第一项: qsort: (只是些概念,了解一下就可以) 基本快速排序的方法,每次把数组分成两分和中间的一个划分值,而对于有多个重复值的数组来说,基本排序的效率较低.集成在C语言库函数里面的的qsort函数,使用 三 路划分的方法解决这个问题.所谓三路划分,是指把数组划分成小于划分值,等于划分值和大于划分值的三个部分. 函数对buf 指向的数据按升序排序. 使用方法: void qsort( void *base, size_t num, size_t width, int (__cdecl *c

Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}, STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73,

第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}, STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73,