Golang は比較的新興のオープンソースで高性能なプログラミング言語であり、その機能の 1 つは関数の defer キーワードです。このキーワードを使用すると、リソースのクリーンアップやログ出力など、関数の終了前に必要な操作を実行できます。また、例外を処理するためにも使用できるため、コードがより堅牢で信頼性が高くなります。この記事では、読者がこの機能をより上手に使用できるように、例外処理における Golang 関数の defer キーワードの適用について詳しく説明します。
1. defer の使用方法
Golang では、defer キーワードを使用して、関数の終了後に実行される関数呼び出しを定義できます。 defer の特別な点は、関数の途中で例外が発生したかどうかに関係なく、関数が戻る前に実行されることです。例:
func demo() { defer fmt.Println("defer end.") fmt.Println("normal flow.") }
上記のコードでは、print ステートメント「normal flow.」が defer ステートメント「defer fmt.Println("defer end.")」の前に実行されます。
さらに、関数内で複数の defer ステートメントが使用されている場合、それらの実行順序はスタック上にあり、後で定義された defer ステートメントが最初に実行されます。例:
func demo() { defer fmt.Println("defer 1.") defer fmt.Println("defer 2.") fmt.Println("normal flow.") }
上記のコードでは、ステートメント「normal flow.」が最初に出力され、次に「defer 2.」、最後に「defer 1.」が出力されます。
2. 例外処理の遅延
通常の使用に加えて、遅延はコード内の例外を処理するためにも使用できます。例外とは、プログラムの実行中に発生するエラーであり、不正な入力、論理エラー、システム エラーなど、さまざまな理由が考えられます。 Golang では、panic/defer/recover の 3 つのキーワードを通じて例外を処理できます。その中で、panic は例外を引き起こし、recover は例外をキャッチして処理し、defer は例外が処理された後に必要なクリーンアップ操作を実行します。以下は、panic/defer/recover の使用法を示す実践的な例です。
func catchError() { defer func() { if err := recover(); err != nil { fmt.Println("recovered from: ", err) } }() fmt.Println("start") panic("error occurs!") fmt.Println("end") }
上記のコードでは、catchError 関数を呼び出し、最初にステートメント "start" を出力し、次に、panic を使用してエラーを引き起こします。例外がスローされ、「エラーが発生しました!」と出力されます。この時点で、プログラムは中断され、catchError 関数で定義された遅延に入ります。この defer には、現在例外をキャッチしたかどうかを判定する if 文があり、例外をキャッチした場合は fmt.Println が呼び出されて「recovered from:」され、例外情報 err が出力されます。
この例は、関数内で例外が発生したときに、Golang の Panic/defer/recover キーワードを使用して、それに応じてプログラムを処理できることを示しています。 defer キーワードはどのような状況でも実行されるため、ファイルを閉じる、リソースを解放するなど、プログラムで例外が発生したときに defer を使用して必要なクリーンアップ操作を実行できます。
3. defer に関する注意事項
defer キーワードを使用する場合は、次の点に注意する必要があります:
func testLoop() { for i := 0; i < 5; i++ { defer fmt.Println("defer: ",i) } fmt.Println("test loop done.") }
上記のコードでは、遅延テストにループ構造を使用しています。ループ内で使用されているリソースを解放できるように、各ループの最後に最初に defer ステートメントが実行されるようにします。ただし、上記のコードでは、defer ステートメントが LIFO (後入れ先出し) で実行されるため、最終的に出力されるのは、「defer: 4, defer: 3, ..., defer: 0」ではなく「testloopned.」です。 .「どうやって解決するの? 1 つの方法は、コードを次のように変更することです:
func testLoop() { for i := 0; i < 5; i++ { defer func(i int) { fmt.Println("defer: ", i) }(i) } fmt.Println("test loop done.") }
この方法では、defer ステートメントにクロージャを追加し、現在の i 値をクロージャ関数に直接渡し、後で実行できるようにします。正しい値を呼び出します。ご覧のとおり、コードをこのように変更した後、「テスト ループが完了しました。」と「defer: 4, defer: 3, ..., defer: 0.」が正常に出力されました。
4. 概要
Golang では、defer キーワードは非常に重要な機能です。ファイルを閉じる、リソースを解放するなど、関数のクリーンアップ操作を実行するために使用できます。さらに、関数内で例外が発生した場合、defer ステートメントは例外をキャッチして処理する上で一定の役割を果たすこともできます。 defer を使用する場合は、プログラム開発でこの機能を最大限に活用し、プログラムをより堅牢で信頼性の高いものにするために、その使い方をマスターし、関連する予防措置に注意を払う必要があります。
以上がGolang関数におけるdeferキーワードの例外処理方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。