【问题标题】:panic and recover from a package恐慌并从包裹中恢复
【发布时间】:2014-09-26 20:51:34
【问题描述】:

我正在尝试弄清楚 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! 从未打印出来?

【问题讨论】:

    标签: go


    【解决方案1】:

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

    specification 谈到了调用recover的延迟函数:

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

    这是微妙的,但它不允许间接调用恢复。另外,recover 的返回值部分提到了对延迟函数的直接调用:

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

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

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

    【讨论】:

      【解决方案2】:

      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,你不会捕捉到恐慌。

      【讨论】:

        猜你喜欢
        • 2015-10-20
        • 1970-01-01
        • 2019-10-07
        • 2017-05-07
        • 2018-05-28
        • 1970-01-01
        • 2022-06-27
        • 2015-04-29
        • 1970-01-01
        相关资源
        最近更新 更多