golang-recover错误
目录
golang recover错误
可以 recover 的错误
- 显式触发的
panic通过panic("error message")主动抛出的错误,只要在 同一goroutine 的defer链中调用recover,即可捕获并恢复。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
panic("user-triggered panic")- 运行时错误(部分)
如切片越界、类型断言失败、空指针解引用等运行时
panic,只要在defer中正确使用recover, 技术上可以捕获 。但程序可能处于不可信状态,继续执行需谨慎。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from runtime error:", r)
}
}()
var a []int
fmt.Println(a[10]) // 越界访问,触发panic- 自定义类型错误
通过
panic抛出自定义类型(如结构体或错误接口),recover可以捕获并处理。
panic(fmt.Errorf("custom error"))不能 recover 的错误
- 其他goroutine未处理的
panic每个goroutine需独立处理自己的panic。若某goroutine未在其内部defer中调用recover,该panic会导致 整个程序崩溃 ,主goroutine无法捕获。
go func() {
panic("goroutine panic") // 主goroutine无法捕获此panic
}()- 程序已终止的情况
若已调用
os.Exit()或发生致命错误(如内存耗尽),recover无法恢复。 - 非
defer上下文中的panicrecover仅在defer函数中调用有效,且必须位于触发panic的同一函数调用栈中。
func main() {
panic("panic outside defer") // 无法被后续的defer捕获
defer func() { recover() }() // 此处defer不会执行
}- 重复调用
panic若在defer中再次触发panic且未被捕获,程序仍会崩溃。
defer func() {
recover()
panic("re-panic") // 未被捕获,导致程序终止
}()
panic("initial panic")- CGO或系统级错误(部分)
某些底层系统错误(如栈溢出、内存段错误)可能绕过Go的
panic/recover机制,直接终止程序。
关键规则总结
- 作用域限制
recover仅在当前goroutine的defer函数中有效。 - 运行时错误的可恢复性 技术上可捕获,但程序状态可能损坏,需谨慎处理。
- 设计建议
- 仅对可预测的错误使用
panic/recover(如输入验证失败)。 - 避免依赖
recover处理不可恢复错误(如内存越界),应确保程序健壮性。
通过合理使用
defer
和
recover
,可以优雅处理局部错误,但需理解其局限性以避免误用。