ホームページ >バックエンド開発 >Golang >ローカル変数を使用したパニックリカバリが Go の戻り値を変更しないのはなぜですか?

ローカル変数を使用したパニックリカバリが Go の戻り値を変更しないのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-29 23:31:29534ブラウズ

Why Does Panic Recovery with Local Variables Not Change the Returned Values in Go?

ローカル変数を使用したパニック リカバリが Go で機能しないのはなぜですか?

Go では、エラー処理にパニックとリカバリを使用するのが一般的です。 。ただし、パニック回復で戻り値にローカル変数を使用する場合、動作には微妙な違いがあります。

次のコードを考えてみましょう。

<code class="go">func main() {
    result, err := foo()
    fmt.Println("result:", result)
    if err != nil {
        fmt.Println("err:", err)
    }
}

func foo() (result int, err error) {
    defer func() {
        if e := recover(); e != nil {
            result = -1
            err = errors.New(e.(string))
        }
    }()
    bar()

    result = 100
    err = nil
    return
}

func bar() {
    panic("panic happened")
}</code>

bar() でパニックが発生すると、recover( ) 遅延クロージャー内の関数が実行されます。 result に -1 を代入し、エラー オブジェクトを作成します。このコードの出力は正しいです:

result: -1
err: panic happened

ただし、戻り値にローカル変数を使用する場合:

<code class="go">func main() {
    result, err := foo()
    fmt.Println("result:", result)
    if err != nil {
        fmt.Println("err:", err)
    }
}

func foo() (int, error) {
    var result int
    var err error
    defer func() {
        if e := recover(); e != nil {
            result = -1
            err = errors.New(e.(string))
        }
    }()
    bar()

    result = 100
    err = nil
    return result, err
}

func bar() {
    panic("panic happened")
}</code>

この場合、出力は異なります:

result: 0

これは、recover() 関数がローカル変数 'result' に -1 を代入するためです。ただし、関数は名前付きの戻り値の結果 (ゼロで初期化された) を返すため、ローカル変数の代入は効果がありません。

この動作の理由は、Go ツアーの基本にあります。

"名前付き戻り値は...関数の先頭で定義された変数として扱われます。"

名前付き戻り値を使用する場合、defer クロージャ内での変更は戻り値に反映されます。ただし、ローカル変数を使用する場合、変更はローカル スコープにのみ反映され、戻り値には反映されません。

以上がローカル変数を使用したパニックリカバリが Go の戻り値を変更しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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