go - panic 并从包裹中恢复

标签 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!

为什么 错误消息已恢复! 从未打印过?

最佳答案

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

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

Suppose a function G defers a function D that calls recover and a panic occurs in a function on the same goroutine in which G is executing. When the running of deferred functions reaches D, the return value of D's call to recover will be the value passed to the call of panic.

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

The return value of recover is nil if any of the following conditions holds:

  • recover was not called directly by a deferred function.

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

关于go - panic 并从包裹中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26068116/

相关文章:

go - 如何通过调用结构方法来启动/停止功能

go - 从接口(interface)中获取所有字段

go - 如何在 Go 中使用 reflect 获取 map 接口(interface)的值?

go 变量作用域和阴影

iis - 在 IIS 上运行 go web 应用程序

go - 我正在尝试将 Cobra 集成到我的程序中

go - 我们可以为 Go 中的错误创建子类型吗?

http - 如何在 Go 中为来自同一个监听器的 SSH 和 HTTP(S) 流量提供服务?

go - 有没有一种好方法可以不在 json 有效负载中公开某些结构属性?

java - gRPC:如何使用 Go 服务器在 Java 客户端中获取多个返回值