为什么在被defer函数调用的函数中,Golang无法从panic中恢复?

huangapple go评论76阅读模式
英文:

Why golang can not recover from a panic in a function called by the defer function

问题

上面的代码无法从 panic 中恢复,而下面的代码可以。

这是因为在第一个代码示例中,myRecover() 函数被作为一个单独的函数调用来执行,而不是作为一个匿名函数传递给 defer 语句。因此,当 panic 发生时,myRecover() 函数无法捕获到 panic,并进行恢复。

而在第二个代码示例中,recover() 函数被直接嵌入到了匿名函数中,并在 defer 语句中执行。这样做的话,当 panic 发生时,recover() 函数能够捕获到 panic,并返回 panic 的值,从而使得程序能够继续执行后续的代码。

因此,第二个代码示例可以成功地从 panic 中恢复,而第一个代码示例无法实现这个功能。

英文:
package main

import "fmt"

func myRecover() {
	if r := recover(); r != nil {
		fmt.Println(r)
	}
}

func main() {
	defer func() {
		myRecover()
	}()
	panic("The gas price is skyrocketing!")
}

The code above can not recover from the panic somehow the code below can.

package main

import "fmt"

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
		}
	}()
	panic("The gas price is skyrocketing!")
}

It is so confusing. I want to know why.

答案1

得分: 1

规范中提到:

> 如果满足以下任何条件,则 recover 的返回值为 nil:
> - ...
> - recover 不是由延迟函数直接调用的。

在第一个示例中,recover 不是由延迟函数直接调用的。在这种情况下,recover 函数始终返回 nil

您可以通过直接延迟函数来使用 myRecover

func main() {
    defer myRecover()
    panic("The gas price is skyrocketing!")
}
英文:

The specification says:

> The return value of recover is nil if any of the following conditions holds:
> - ...
> - recover was not called directly by a deferred function.

In the first example, recover is not called directly by the deferred function. The recover function always returns nil in this case.

You can use myRecover by deferring the function directly.

func main() {
	defer myRecover()
	panic("The gas price is skyrocketing!")
}

huangapple
  • 本文由 发表于 2022年6月17日 05:08:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/72651899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定