ローカル変数を使用したパニック リカバリが 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 サイトの他の関連記事を参照してください。