无效用法
1、pnic在前不会往下执行
func case2() {
panic("panic")
defer func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}()
}
2、f2()在方法中已经执行完recover了,不会影响到case2中的panic
func case2() {
f2()
panic("panic")
}
func f2() {
defer func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}()
}
3、
over() 只有在当前 正在执行的 defer 函数内部直接调用时才有效。 在 f2() 中注册的 defer func(){...}() 是在 f2() 被调用时压入 defer 栈的。 当 case2() 中发生 panic 时,Go 开始执行已注册的 defer 函数(即 f2())。 此时再调用 f2(),又注册一个新的 defer(即 func(){ recover() }),但此时已经 在 panic 流程中了,新注>册的 defer 已经来不及触发 recover()。 简单理解:recover() 必须出现在 panic 触发前就已经注册好的 defer 函数中。 如果 recover() 是在 panic 发生之后,通过 defer 函数再注册 defer,那它就无法捕获到 panic。
func case2() {
defer func() {
f2()
}()
panic("panic")
}
func f2() {
defer func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}()
}
4、 没有执行返回的func
func case2() {
defer f3()
panic("panic")
}
func f3() func() {
return func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}
}
有效用法
1、先把recover注册进入defer中
func case2() {
defer func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}()
panic("panic")
}
2、:立即调用返回的闭包函数,并在其内部执行 recover() 来捕获 panic
func case2() {
defer f3()()
panic("panic")
}
func f3() func() {
return func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}
}