当前位置:网站首页>GO语言-panic和recover
GO语言-panic和recover
2022-06-23 03:56:00 【一边学习一边哭】
前言
go语言追求简洁,所以go语言中没有try...catch语句。因为go语言的作者认为将异常和控制语句混在一起,很容易让这个程序变得混乱,异常也很容易被滥用。
所以在go语言中,为了防止异常被滥用。我们常常使用函数的返回值来返回错误,而不是用异常来代替错误。
如果在一些场景下确实需要处理异常,就可以使用panic和recover。panic用来抛出异常,recover用来恢复异常。
panic
panic触发流程:
- 如果函数F中书写并触发了panic语句,会终止其后要执行的代码。在panic所在函数F内如果存在要执行的defer函数列表,则按照defer书写顺序的逆序执行;
- 如果函数G调用函数F,则函数F panic后返回调用者函数G。函数G中,调用函数F语句之后的语句都不会执行。假如函数G中也有要执行的defer函数列表,则按照defer书写顺序的逆序子还行;
- 退出整个goroutine,并报告错误。
func main() {
defer fmt.Println("main---1---")
defer fmt.Println("main---2---")
fmt.Println("main---3---")
mytest(1)
defer fmt.Println("main---4---")
fmt.Println("main---5---")
}
func mytest(num int) {
defer fmt.Println("mytest---1---")
defer fmt.Println("mytest---2---")
fmt.Println("mytest---3---")
if num == 1 {
panic("出现异常,抛出panic")
}
defer fmt.Println("mytest---4---")
fmt.Println("mytest---5---")
}
代码执行流程:
从main函数进入 --> 遇到main函数中的2条defer语句 --> 打印"main---3---" --> 进入mytest函数
--> 遇到mytest函数中2条defer语句 --> 打印"mytest---3---" --> if语句为true触发panic --> 逆序执行mytest函数中的panic前的2条defer语句 --> 返回外部函数(main函数) --> 逆序执行main函数中的mytest函数前的2条defer语句 --> 抛出异常
由于panic抛出异常,可以看到mytest函数panic语句后面的语句都不被执行;返回外部函数后,mytest函数后的语句也都不被执行。
recover
- recover的作用是捕获panic,从而恢复正常代码执行;
- recover必须配合defer使用;
- recover没有传入参数,但是有返回值,返回值就是panic传递的值
recover示例
defer func() {
if msg := recover(); msg != nil {
fmt.Println("panic信息:", msg, "---recover恢复---")
}
}()panic示例中的示例,如果在mytest中加入recover将panic恢复后,执行效果和顺序是如何的呢?
func main() {
defer fmt.Println("main---1---")
defer fmt.Println("main---2---")
fmt.Println("main---3---")
mytest(1)
defer fmt.Println("main---4---")
fmt.Println("main---5---")
}
func mytest(num int) {
defer func() {
if msg := recover(); msg != nil {
fmt.Println("panic信息:", msg, "---recover恢复---")
}
}()
defer fmt.Println("mytest---1---")
defer fmt.Println("mytest---2---")
fmt.Println("mytest---3---")
if num == 1 {
panic("出现异常,抛出panic")
}
defer fmt.Println("mytest---4---")
fmt.Println("mytest---5---")
}

代码执行流程:
从main函数进入 --> 遇到main函数中的2条defer语句 --> 打印"main---3---" --> 进入mytest函数
--> 遇到mytest函数中3条defer语句 --> 打印"mytest---3---" --> if语句为true触发panic --> 逆序执行mytest函数中的panic前的3条defer语句 --> 执行到第三条defer时,recover恢复恐慌并输出信息 --> 返回外部函数(main函数) --> 遇到mytest函数后的1条defer语句 --> 打印"mytest---5---" --> 逆序执行main函数中的3条defer语句
由于recover恢复恐慌,所以程序就不会因为panic而退出执行,所以mytest返回外部函数后,外部函数还能够正常执行下去。
边栏推荐
- Mongodb sharding principle
- STM32cube CMSIS_V2 freeRTOS Queue 队列使用
- Implementation of slider view
- BGP second test
- Rtklib new version 2.4.3 B34 test comparison
- 8 years' experience: monthly salary of 3000 to 30000, the change of Test Engineer
- Jetpack compose menubar Desktop Menu from door opening to entry
- IDEA 代码开发完毕后,提交代码,提交后发现分支不对,怎么撤回
- Image noise reduction denoise AI
- [leetcode] longest increasing subsequence problem and its application
猜你喜欢

UI automation positioning edge -xpath actual combat

Complete one-time GC process of JVM principle

stm32时钟树错误配置导致 开机进入硬中断

Snippet Manager snippetslab

gis利器之Gdal(三)gdb数据读取

MCS:连续随机变量——LogNormal分布

Introduction to s file generated by TEQC for GNSS data quality analysis

How to conduct exploratory data analysis

MCS: continuous random variable - student's t distribution

渗透测试基础 | 附带测试点、测试场景
随机推荐
Snippet Manager snippetslab
【微服务|Nacos】Nacos版本相关问题一览
Mongodb sharding principle
Go 分组 & 排序
Difficult to find a job in a bad environment? Ali on three sides. Fortunately, he has made full preparations and has offered
Missing essential plugin
MCS:离散随机变量——Bernoulli分布
H5 适配全面屏
CF【1700D】D. River Locks(dp、二分、数学)
Drag and drop frame
How to conduct exploratory data analysis
MCS:连续随机变量——LogNormal分布
第九章 APP项目测试(1)
MySQL自定义序列数的实现
Seata四大模式之XA模式详解及代码实现
【微服务|Nacos】Nacos实现多环境和多租户的数据隔离
Arduino flame sensor (with code)
Swiftui 2.0 course notes Chapter 5
MCS:离散随机变量
软件项目管理 8.4.软件项目质量计划