go - 为什么 `defer recover()` 没有捕捉到 panic ?

标签 go deferred-execution

为什么调用 defer func() { recover() }() 成功地恢复了一个 panic 的 goroutine,但调用 defer recover() 却没有?

作为一个简约的例子,这段代码不会 panic

package main

func main() {
    defer func() { recover() }()
    panic("panic")
}

但是,直接用recover替换匿名函数会发生 panic

package main

func main() {
    defer recover()
    panic("panic")
}

最佳答案

引用内置函数的文档recover() :

If recover is called outside the deferred function it will not stop a panicking sequence.

在您的第二种情况下, recover() 本身就是延迟函数,显然 recover() 不会调用自己。所以这不会停止 panic 序列。

如果 recover() 本身会调用 recover(),它会停止 panic 序列(但它为什么会这样做呢?)。

另一个有趣的例子:

以下代码也不会 panic (在 Go Playground 上尝试):

package main

func main() {
    var recover = func() { recover() }
    defer recover()
    panic("panic")
}

这里发生的是我们创建一个函数类型的 recover 变量,该变量具有调用内置 recover() 函数的匿名函数的值。我们指定调用 recover 变量的值作为延迟函数,因此调用内置的 recover() 会停止 panic 序列。

关于go - 为什么 `defer recover()` 没有捕捉到 panic ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29518109/

相关文章:

go - 附加到 for 循环中的 slice 并产生意外结果

javascript - 可以使用匿名函数来延迟 js 的加载吗?

javascript - 外部异步/延迟 javascript 是否保证在窗口 onload 事件之前执行?

jquery-deferred - jQuery - 延迟等待一组 ajax 请求以完成甚至失败

windows - go 命令在我的 Windows 机器上运行缓慢,在我的 Linux 上运行良好

go - 确定 POST 数据值是否匹配结构字段类型

go - 如何获取相对于导入包路径的文件路径?

go - 在 go channel 上选择内部范围

python - 扭曲: `defer.execute` 和 `threads.deferToThread` 之间的区别

GWT - 实现 TabLayoutPanel 的编程选项卡选择,然后滚动到选项卡中包含的特定元素?