ホームページ  >  記事  >  バックエンド開発  >  Go のネストされた遅延関数で「recover()」が機能しないのはなぜですか?

Go のネストされた遅延関数で「recover()」が機能しないのはなぜですか?

DDD
DDDオリジナル
2024-11-24 08:42:14637ブラウズ

Why Doesn't `recover()` Work in Nested Deferred Functions in Go?

入れ子になった遅延関数で Recover() が失敗する理由

次の 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。