パニック リカバリーは関数リテラルのローカル変数を変更できますか?
Go では、名前付き戻り値を操作するときに defer ステートメントを使用できます。値を返す前に値を変更します。ただし、関数リテラルでローカル変数を使用する場合、この動作は一貫していません。
次のコードを考えてみましょう:
<code class="go">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>
このコードは期待どおりに動作し、result を -1 に設定し、err を a に設定します。パニックから回復した後のカスタム エラー メッセージ。ただし、関数リテラル内でローカル変数を使用すると、動作が変わります。
<code class="go">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>
この場合、結果は -1 ではなく 0 にリセットされます。これは、関数リテラルの defer ステートメントは、名前付き戻り値がスコープ内にないため、アクセスしたり変更したりできないためです。
Go ドキュメントによると、「...遅延関数が関数リテラルの場合」周囲の関数がリテラル内のスコープ内にある名前付き結果パラメータを持っている場合、遅延関数は返される前に結果パラメータにアクセスして変更する可能性があります。
したがって、試行するときは名前付き戻り値を使用することが重要です。関数リテラル内の defer ステートメントを使用してそれらを変更します。このような場合、ローカル変数にアクセスしたり変更したりすることはできません。
以上がPanic Recovery は Go の関数リテラルのローカル変数を変更できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。