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

时间:2018-03-18 04:30:12

标签: 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()包装在更大的延迟函数中:

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

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

1 个答案:

答案 0 :(得分:4)

这是因为recover如果没有被延期函数直接调用将是nil

以下是golang spec

的摘录
  

如果满足以下任何条件,则恢复的返回值为零:

     
      
  1. 恐慌的论点是nil;
  2.   
  3. goroutine并不恐慌;
  4.   
  5. 未通过延期功能直接调用recover。
  6.   

有关详细信息,请查看完整规范here