恐慌并从包中恢复

时间:2014-09-26 20:51:35

标签: go

我正在试图找出panic()recover()的工作原理..

日志包

package log

import (
    "fmt"
)

func Recover() {
    fmt.Println("Recovering!")
    if err := recover(); err != nil {
        fmt.Println("Error message recovered!")
    }
}

主程序包

package main

import (
    "fmt"
    log "www/pkg/log"
)

func main() {
    defer func() {
        log.Recover()
    }()

    panic("Fake error!")
}

输出

Recovering!
panic: Fake error!

为什么Error message recovered!从未打印过?

2 个答案:

答案 0 :(得分:2)

应用程序必须直接从延迟函数调用recover来处理恐慌。

specification讨论了调​​用recover的延迟函数:

  

假设函数G推迟调用恢复的函数D,并且在执行G的同一goroutine上的函数中发生恐慌。当延迟函数的运行达到D时,D调用recover的返回值将是传递给恐慌调用的值。

它很微妙,但它不允许间接调用恢复。此外,来自恢复的返回值的段落提到了来自延迟函数的直接调用:

  

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

     
      
  • 恢复不是由延迟函数直接调用的。
  •   

我最近被这个问题抓住了。由于规范非常简洁,有时需要仔细阅读以获取一些要点。

答案 1 :(得分:1)

revocer仅指执行当前的goroutine:文档说:

Executing a call to recover inside a deferred function **(but not any function called by it)** stops the panicking sequence by restoring normal execution

当你调用另一个函数时,它没有恐慌,因此在它的中间调用recover返回nil,你没有发现恐慌。