ホームページ >バックエンド開発 >Golang >特にすでにパニックになっている場合、defer 関数内でパニックになっても大丈夫ですか?

特にすでにパニックになっている場合、defer 関数内でパニックになっても大丈夫ですか?

WBOY
WBOY転載
2024-02-11 20:33:081005ブラウズ

在 defer 函数内部发生恐慌是否可以,特别是当它已经发生恐慌时?

defer 関数内でパニックが発生した場合、影響はありますか?これは、特にパニック状況が発生した場合によくある質問です。 PHP では、defer 関数を使用して、現在の関数が戻る前にいくつかのクリーンアップ操作を実行します。パニックが発生すると、プログラムは実行を直ちに停止し、すべての遅延関数が後入れ先出しの順序で実行されます。したがって、パニックが発生した後でも、遅延関数は実行されます。これは、リソースの解放やエラー処理などのタスクを処理するのに役立ちます。何が起こっても、defer 関数は常に確実に実行され、コードの整合性と安定性が保証されます。

質問内容

func sub(){
    defer func (){
        panic(2)
    }()
    panic(1)
}

func main(){
    defer func(){
        x:=recover()
        println(x.(int));
    }()
    sub()
}

このコードを試してみたところ、最初のパニック panic(1) が 2 番目のパニック panic(2) によって「上書き」されているようです。

でも、こんなことして大丈夫でしょうか?それとも、遅延関数内でパニックを引き起こす可能性のある Golang 関数を呼び出していますか?

(C では、デストラクターから例外をスローすることはほとんど受け入れられません。スタックが巻き戻されている場合、プログラムが終了します。Golang でも同様の方法でパニックを起こすのは良くないのではないかと思います。)

解決策

はい、大丈夫です。遅延関数によって引き起こされるパニックは実際には新しい特別な状態ではなく、単にパニック シーケンスが停止しないことを意味します。

サンプル コードは、問題がないことも証明しています。 panic() を呼び出しても recover() に渡すことができます。遅延機能を停止するには、upper" レベルが呼び出されます。

仕様: パニックへの対応:

ここで注意すべき点は、遅延関数内で panic() を呼び出した場合でも、他のすべての遅延関数は引き続き実行されるということです。また、遅延関数の recover() を使用しない panic() は、既存のパニックを「上書き」するのではなく「ラップ」します (ただし、recover()この呼び出しは、渡された最後の panic() 呼び出しのみを返します)。

この例を参照してください:

リーリー

出力 (Go Playground で試してください):

c2e572c1c34a0369ef7​​ 989373914f540

すべての遅延関数が panic() を呼び出した場合でも、すべての遅延関数が実行され、出力される最終パニック シーケンスには、すべての panic() 呼び出しに渡された値が含まれます。

遅延関数内で recover() を呼び出すと、この「回復」ステータスまたは情報が最終出力にも表示されます。 リーリー

出力 (

Go Playground で試してください): リーリー

以上が特にすでにパニックになっている場合、defer 関数内でパニックになっても大丈夫ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。