GO语言-panic和recover

前言

        go语言追求简洁,所以go语言中没有try...catch语句。因为go语言的作者认为将异常和控制语句混在一起,很容易让这个程序变得混乱,异常也很容易被滥用。

        所以在go语言中,为了防止异常被滥用。我们常常使用函数的返回值来返回错误,而不是用异常来代替错误。

        如果在一些场景下确实需要处理异常,就可以使用panic和recover。panic用来抛出异常,recover用来恢复异常。

panic

panic触发流程:

  1. 如果函数F中书写并触发了panic语句,会终止其后要执行的代码。在panic所在函数F内如果存在要执行的defer函数列表,则按照defer书写顺序的逆序执行;
  2. 如果函数G调用函数F,则函数F panic后返回调用者函数G。函数G中,调用函数F语句之后的语句都不会执行。假如函数G中也有要执行的defer函数列表,则按照defer书写顺序的逆序子还行;
  3. 退出整个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

  1. recover的作用是捕获panic,从而恢复正常代码执行;
  2. recover必须配合defer使用;
  3. 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返回外部函数后,外部函数还能够正常执行下去。

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值