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

Go 为什么recover()在嵌套的延迟函数中不起作用?,go,error-handling,Go,Error Handling,我正在Golang测试panic/recover。此简单程序按预期工作: package main import "fmt" func printRecover() { r := recover() fmt.Println("Recovered:", r) } func main() { defer printRecover() panic("OMG!") } 输出: Recovered: OMG! 但是,如果我将函数printRecover()包装在

我正在Golang测试
panic/recover
。此简单程序按预期工作:

package main

import "fmt"

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

func main() {
    defer printRecover()

    panic("OMG!")
}
输出:

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

package main

import "fmt"

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

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

    panic("OMG!")
}
它无法恢复,让恐慌过去:

Recovered: <nil>
panic: OMG!

goroutine 1 [running]:
main.main()
    /tmp/sandbox898315096/main.go:15 +0x60
已恢复:
恐慌:天哪!
goroutine 1[正在运行]:
main.main()
/tmp/sandbox898315096/main.go:15+0x60

有人能解释一下区别吗?

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

这是《golang规范》的摘录

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

  • 恐慌的论据是零
  • 戈罗廷并没有惊慌失措
  • 延迟函数未直接调用recover。

  • 有关更多信息,请查看完整规范

    ,以及带有规范链接的答案;还说“在延迟函数(但不是它调用的任何函数)内执行恢复调用…”