golang 的 panic reocver 和 error,延伸出变量作用域

本文详细探讨了Go语言中defer、recover和panic、error的关系。在函数ErrorHandlingKeyPoint4Adv中,展示了当发生error时,recover无法捕获,程序继续执行;而当触发panic时,recover能够捕获到,但返回的错误信息会被新定义的error覆盖,导致外部无法正确获取原始panic信息。通过案例分析,揭示了Go语言中错误处理的微妙之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 golang 的 defer 函数中的 recover() 只能捕获 panic, 不能捕获 error。如果发生 error, 后面的代码还会继续;如果发生 panic,后面的代码不会被执行。

func ErrorHandlingKeyPoint4Adv() (err error) {
	fmt.Println("In the ErrorHandlingKeyPoint4Adv 想测试 recover 后再产生 error 怎么处理;" +
		"后来精准发现  recover 只能捕获 panic, 不能捕获 error")
	defer func() {
		fmt.Printf("===In the defer func===\n")
		// https://www.runoob.com/go/go-scope-rules.html
		// 如果下面的代码走 case 1 即手动产生 error , 则 defer 函数里的 recover() 是不能捕获到该 error 的
		// 如果下面的代码走 case 2 即手动产生 panic , 则 defer 函数里的 recover() 是会捕获 panic 的, 但是外层函数的调用者
		// 只能获取到 the panic from the business code 而不是 the error from recover,因为这涉及到变量作用域的问题,
		// if err := recover() 相当于定义了一个新的局部变量(注意写的是 :=),下面函数体里的
		// err = errors.New("the error from recover") 相当于给该新局部变量赋值 不是 给函数返回值的 err 赋值;
		// 你可能会想如果 不写 if err := recover() 写 if err = recover() 这样就给 函数返回值的 err 赋值了,
		// 但这样会报赋值类型不对,因为 recover() 的返回值类型是 interface{} 不是 error 类型。
		if err := recover(); err != nil {
			fmt.Println("got the panic not error")
			fmt.Println(err)
			err = errors.New("the error from recover")
		}
	}()
	fmt.Printf("For ErrorHandlingKeyPoint4Adv: test the panic\n")
	// 感受 error 和 panic 的差异:
	// Case 1:
	// err = errors.New("the error from the business code")
	// Case 2:
	panic("the panic from the business code")
	fmt.Printf("For ErrorHandlingKeyPoint4Adv: test the panic222\n")
	return
}

对于 case 1 的运行结果:

In the ErrorHandlingKeyPoint4Adv 想测试 recover 后再产生 error 怎么处理;后来精准发现  recover 只能捕获 panic, 不能捕获 error
For ErrorHandlingKeyPoint4Adv: test the panic
For ErrorHandlingKeyPoint4Adv: test the panic222
===In the defer func===
the error from the business code

对于 case 2 的运行结果:

In the ErrorHandlingKeyPoint4Adv 想测试 recover 后再产生 error 怎么处理;后来精准发现  recover 只能捕获 panic, 不能捕获 error
For ErrorHandlingKeyPoint4Adv: test the panic
===In the defer func===
got the panic not error
the panic from the business code
<nil>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值