为什么recover() 在嵌套的延迟函数中不起作用?

Nic*_*Lee 2 error-handling go

我正在panic/recoverGolang 中测试。这个简单的程序按预期工作:

package main

import "fmt"

func printRecover() {
    r := recover()
    fmt.Println("Recovered:", r)
}

func main() {
    defer printRecover()

    panic("OMG!")
}
Run Code Online (Sandbox Code Playgroud)

输出:

Recovered: OMG!
Run Code Online (Sandbox Code Playgroud)

但是,如果我将该函数包装printRecover()在一个更大的延迟函数中:

package main

import "fmt"

func printRecover() {
    r := recover()
    fmt.Println("Recovered:", r)
}

func main() {
    defer func() {
        printRecover()
    }()

    panic("OMG!")
}
Run Code Online (Sandbox Code Playgroud)

它不会恢复并让恐慌持续下去:

Recovered: <nil>
panic: OMG!

goroutine 1 [running]:
main.main()
    /tmp/sandbox898315096/main.go:15 +0x60
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下区别吗?

She*_*tyh 6

这是因为recover将是nil,如果不是直接由递延函数调用

这是golang规范的摘录

如果满足以下任一条件,recover 的返回值为 nil:

  1. 恐慌的论点是零;
  2. goroutine 不会恐慌;
  3. 恢复不是由延迟函数直接调用的。

有关更多信息,请在此处查看完整规范

  • 这是为什么?为什么延迟函数调用的函数无法感知恐慌? (2认同)