go 的 revover 实现原理

2022-08-31  本文已影响0人  wayyyy
image.png

recover() 函数实际被调用的是src/runtime/panic.go:gorecover()

gorecover

runtime.gorecover 函数实现很简短

func gorecover(arg uintptr) interface{} {
    gp := getg()
    p := gp._panic()  // 获取panic实例,只有发生了panic,实例才不为nil
    if p != nil && !p.goexit && !p.recovered && arg == uintptr(p.argp) {
        p.recovered = true
        return p.arg
    }    

    return nil
}
总结

通过以上分析,我们可以很好地回答以下问题了:

  1. 为什么recover()函数一定要在defer()函数中才生效?
    如果recover()函数不在defer()函数中,那么defer()函数可能出现在panic之前,也可能出现在panic之后。出现在panic之前,因为找不到panic实例而无法生效,出现在panic之后,代码没有机会执行,所以recover()函数必须存在于recover()函数中才会生效。

  2. panic 被 recover 之后,无法再次被 recover 捕获

  3. 假如defer()函数中调用了函数A,为什么A中的recover()不能生效?

上一篇下一篇

猜你喜欢

热点阅读