ホームページ >バックエンド開発 >Golang >Go のパニック回復中に遅延関数はローカル変数を変更できますか?

Go のパニック回復中に遅延関数はローカル変数を変更できますか?

DDD
DDDオリジナル
2024-10-29 22:45:03801ブラウズ

Can Defer Functions Modify Local Variables During Panic Recovery in Go?

ローカル変数を使用したパニック リカバリ

Go では、defer 関数を使用したパニック リカバリにより、周囲の関数内の名前付き戻り値を変更できます。ただし、ローカル変数が戻り値として使用される場合、このメカニズムは期待どおりに機能しません。

名前付き戻り値 (result と err) が defer 関数内で変更される次の例を考えてみましょう:

<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>

このコードはパニックから回復し、名前付き戻り値の結果とエラーを正しく変更します。ただし、ローカル変数が戻り値として使用される次の例を考慮してください:

<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>

この場合、defer 関数は result 変数と err 変数を変更できず、結果が 0 のままの予期しない出力になります。

この動作は、defer ステートメントが周囲の関数自体ではなく関数リテラルに適用されるという事実から発生します。したがって、関数リテラル内ではローカル変数 (result と err) にアクセスできません。対照的に、名前付き戻り値は、本質的に関数の先頭で初期化される変数であるため、関数リテラル内でアクセスできます。

以上がGo のパニック回復中に遅延関数はローカル変数を変更できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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