设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间00 现在时间00 缓存数据 对自己狠一点,逼自己努力,再过几年你将会感谢今天发狠的自己、恨透今天懒惰自卑的自己。晚安!

对自己狠一点,逼自己努力,再过几年你将会感谢今天发狠的自己、恨透今天懒惰自卑的自己。晚安!

查看: 1196|回复: 6

Golang异常控制处理程序错误流程

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:237
  • 打卡月天数:0
  • 打卡总奖励:3488
  • 最近打卡:2025-11-19 21:44:15
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
379
主题
350
精华
0
金钱
4646
积分
803
注册时间
2023-1-4
最后登录
2025-11-19

发表于 2023-5-2 16:06:26 | 显示全部楼层 |阅读模式
panic和recover使用

Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。在Go语言中,设计者们推荐使用多值返回来返回错误。遇到真正的异常的情况下(比如除数为 0了)。才使用Go中引入的Exception处理:defer, panic, recover。
这几个异常的使用场景可以这么简单描述:Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理

使用示例
  1. package main
  2. import "fmt"
  3. func main(){
  4.     fmt.Println("c")
  5.      defer func(){ // 必须要先声明defer,否则不能捕获到panic异常
  6.         fmt.Println("d")
  7.         if err:=recover();err!=nil{
  8.             fmt.Println(err) // 这里的err其实就是panic传入的内容,55
  9.         }
  10.         fmt.Println("e")
  11.     }()
  12.     f() //开始调用f
  13.     fmt.Println("f") //这里开始下面代码不会再执行
  14. }
  15. func f(){
  16.     fmt.Println("a")
  17.     panic("异常信息")
  18.     fmt.Println("b") //这里开始下面代码不会再执行
  19.     fmt.Println("f")
  20. }
复制代码
输出结果:
  1. cad异常信息e
复制代码
注意


  • 利用recover处理panic指令,recover需要定义在defer匿名函数内
  • defer需要在panic之前声明,否则当panic时,recover无法捕获到panic
  • panic无recover情况下,程序会直接崩溃

子函数panic主函数recover
  1. func TestPanic(t *testing.T) {
  2.         defer func() {
  3.                 if err := recover(); err != nil {
  4.                         println("recovered")
  5.                 }
  6.         }()
  7.         subFun()
  8.         subFun()
  9. }
  10. func subFun() {
  11.         println("subFun")
  12.         panic("subFun panic")
  13. }
复制代码
输出结果如下,第一个sunFun后面的代码不会执行
  1. subFunrecovered
复制代码
子协程panic主函数recover
  1. func subFun(i int) {
  2.         fmt.Println("subFun,i=", i)
  3.         panic("subFun panic")
  4. }
  5. func TestSubGoPanic(t *testing.T) {
  6.         defer func() {
  7.                 if err := recover(); err != nil {
  8.                         println("recovered2")
  9.                 }
  10.         }()
  11.         go subFun(3)
  12.         subFun(4)
  13.         println("finish")
  14. }
复制代码
  1. 结果subFun,i= 4recovered2subFun,i= 3--- PASS: TestSubGoPanic (0.00s)panic: subFun panic
  2. goroutine 21 [running]:zh.com/base/err.subFun(0x0?)    /Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:34 +0x89created by zh.com/base/err.TestSubGoPanic    /Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:43 +0x46
复制代码
recover会执行,但是程序崩溃了

使用总结

如果 panic 和 recover 发生在同一个协程,那么 recover 是可以捕获的,如果 panic 和 recover 发生在不同的协程,那么 recover 是不可以捕获的
也就是哪个协程有panic,哪个协程里必须要有recover,否则会把整个程序弄崩溃

使用panic的几点担心


性能

在使用 Golang 进行开发时,遇到 panic 是非常常见的情况。但是,panic 对于性能的影响是相对较小的,尤其是在实际使用中。
首先,Golang 在运行时会维护一个 panic 堆,用于存储栈中的 panic 对象。当程序遇到 panic 时,会将该 panic 对象添加到 panic 堆中。panic 堆的大小是有限的,如果堆中的对象过多,可能会导致 panic 堆溢出,从而影响程序的性能

性能对比
  1. func BenchmarkSubFunWithError(b *testing.B) {
  2.         for i := 0; i < b.N; i++ {
  3.                 go subFunWithError(i)
  4.         }
  5. }
  6. func BenchmarkSubFunWithRecover(b *testing.B) {
  7.         for i := 0; i < b.N; i++ {
  8.                 go subFunWithRecover(i)
  9.         }
  10. }
  11. func subFunWithRecover(i int) {
  12.         //fmt.Println("subFun,i=", i)
  13.         defer func() {
  14.                 if error := recover(); error != nil {
  15.                         //println("subFunWithRecover_recovered")
  16.                 }
  17.         }()
  18.         time.Sleep(time.Second)
  19.         panic("subFun panic")
  20. }
  21. func subFunWithError(i int) error {
  22.         //fmt.Println("subFun,i=", i)
  23.         time.Sleep(time.Second)
  24.         return errors.New("subFunWithError")
  25. }
  26. BenchmarkSubFunWithError-12               673920              1992 ns/op             489 B/op          3 allocs/op
  27. BenchmarkSubFunWithRecover-12            1000000              1229 ns/op             240 B/op          2 allocs/op
复制代码
反而使用panic的性能更好?

安全

另外一个比较担心的点是panic容易导致崩溃,但是如上所示,只要main方法里做好recover,每个go协程使用封装好的带recover的方法来调用,其实并不会有问题
到此这篇关于Golang异常控制处理程序错误流程的文章就介绍到这了,更多相关Golang异常控制内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
19
积分
18
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2023-5-4 01:44:48 | 显示全部楼层
谢谢分享~~~~~
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
17
积分
14
注册时间
2022-12-30
最后登录
2022-12-30

发表于 2023-5-7 05:25:27 | 显示全部楼层
感谢楼主分享~~~~~
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
12
积分
4
注册时间
2023-4-20
最后登录
2023-4-20

发表于 2024-2-17 18:10:53 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
22
积分
24
注册时间
2022-12-27
最后登录
2022-12-27

发表于 2024-10-28 17:58:46 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:无名新人
  • 打卡总天数:1
  • 打卡月天数:0
  • 打卡总奖励:16
  • 最近打卡:2024-12-10 18:28:43
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
30
积分
4
注册时间
2024-3-25
最后登录
2024-12-10

发表于 2025-2-17 08:09:18 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-25
最后登录
2022-12-25

发表于 2025-2-25 01:54:10 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼
4楼
5楼
6楼
7楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表