次の Golang コードを考えてみましょう。
package main import "fmt" func printRecover() { r := recover() fmt.Println("Recovered:", r) } func main() { defer printRecover() panic("OMG!") }
この単純なプログラムは、次のコマンドでパニックと回復に成功します。次の出力:
Recovered: OMG!
ただし、 printRecover() を別の遅延関数でラップするコードは、異なる結果になります:
package main import "fmt" func printRecover() { r := recover() fmt.Println("Recovered:", r) } func main() { defer func() { printRecover() }() panic("OMG!") }
この場合、パニックは回復されず、プログラムがクラッシュします:
Recovered: <nil> panic: OMG! goroutine 1 [running]: main.main() /tmp/sandbox898315096/main.go:15 +0x60
この動作の説明は、Golang でのrecover() の動作方法にあります。言語仕様によると:
The return value of recover is nil if any of the following conditions holds: - panic's argument was nil; - the goroutine is not panicking; - recover was not called directly by a deferred function.
最初の例では、recover() が遅延関数によって直接呼び出されるため、パニック引数が正常に取得されます。ただし、2 番目の例では、recover() は遅延関数によって直接呼び出されるのではなく、遅延関数によって呼び出された関数自体によって呼び出されます。その結果、recover() は nil を返し、パニックは回復されません。
以上がGo のネストされた遅延関数で「recover()」が機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。