Go での defer の使用: ベスト プラクティスと一般的な使用例

PHPz
リリース: 2024-08-20 06:58:02
オリジナル
632 人が閲覧しました

Go では、defer キーワードはリソースを管理し、関数の終了時にクリーンアップ アクションが確実に実行されるようにする強力なツールです。遅延関数は、周囲の関数が正常に戻るか、エラーまたはパニックによって戻るかに関係なく、周囲の関数が戻るときに実行されます。これにより、関数の終了方法に関係なくクリーンアップ コードが確実に実行され、リソース管理がよりシンプルかつ信頼性の高いものになります。

延期に関する重要なポイント:

    実行タイミング: 遅延関数は、実行の完了、return ステートメントの検出、またはパニックにより周囲の関数が戻ったときに、LIFO (後入れ先出し) 順序で実行されます。
  • リソース管理: ファイルやネットワーク接続などのリソースを自動的に閉じたり、ミューテックスのロックを解除したり、その他のクリーンアップ タスクを実行したりするのに役立ちます。
  • 目次

1.複数のdeferステートメントの順序

    2.リソースのクリーンアップ
  • 3.ミューテックスのロックを解除する
  • 4.データベース接続の解放
  • 5.状態を復元中
  • 6.パニックへの対処
  • 7.ロギングとタイミング
  • 8.バッファのフラッシュ
  • 9. HTTP リクエストボディの処理
  • 10.失敗したオープニングを延期せずにクローズするリスク
  • 11.ファイルが開かれたかどうかを確認する前に遅延を使用するリスク
  • 12.結論
  • 1. 複数の defer ステートメントの順序
Go では、関数内の複数の defer ステートメントは、出現した順序と逆の

順序で実行されます。これは、複数のクリーンアップ タスクを管理し、関数の終了時に確実に特定の順序で実行されるようにするのに便利です。

リーリー

Using defer in Go: Best Practices and Common Use Cases出力:

リーリー2. リソースのクリーンアップ
defer の最も一般的な使用法の 1 つは、ファイルなどのリソースが不要になった後に適切に閉じられるようにすることです。

リーリー

os.File は io.ReadCloser を実装しているため、ここで defer を使用すると、ファイルが適切に閉じられ、リソース リークが防止されます。

3. ミューテックスのロックを解除する

同時実行性を使用する場合、デッドロックを防ぐためにロックを解放することが重要です。 defer は、ミューテックスを効果的に管理するのに役立ちます。

リーリー

mu.Unlock() を延期することで、ミューテックスが常に解放されるようになり、コードが理解しやすくなり、エラーが発生しにくくなります。

4. データベース接続の解放

リソースを解放するためにデータベース接続が不要になった場合は、データベース接続を閉じる必要があります。

リーリー

5. 状態の復元


例: 作業ディレクトリの変更と復元

作業ディレクトリを変更する場合は、元の状態に戻すことが重要です。
  • リーリー
  • defer を使用すると、元のディレクトリを自動的に簡単に復元できます。

6. パニックへの対処

例: パニックからの回復

defer を使用すると、パニックから回復し、エラーを適切に処理できます。
  • リーリー
  • パニックを処理する関数を延期することで、予期しないエラーが発生した場合でもアプリケーションの堅牢性を確保できます。

7. ロギングとタイミング

例: タイミング関数の実行

defer は、実行時間の測定や関数終了時のログ記録に役立ちます。
  • リーリー
  • このアプローチにより、タイミング コードが簡素化され、関数の完了時に継続時間が記録されるようになります。

8. バッファのフラッシュ

例: バッファリングされた I/O のフラッシュ

すべてのデータが確実に書き出されるように、バッファリングされた I/O 操作をフラッシュする必要があります。
  • リーリー
  • ここで defer を使用すると、関数が完了する前にバッファリングされたデータが書き込まれることが保証されます。

9. HTTP リクエストボディの処理

例: HTTP リクエスト本文を閉じる

HTTP リクエストボディは io.ReadCloser を実装しているため、リソースを解放してリークを避けるために、使用後にリクエストボディを閉じることが重要です。
  • リーリー
  • req.Body.Close() を延期することで、読み取り中または処理中にエラーが発生した場合でも、ボディが適切に閉じられるようになります。

10. 失敗したオープニングを延期せずにクローズするリスク

Go でファイルまたはその他のリソースを開くときは、リソースが不要になったら確実に適切に閉じることが重要です。ただし、エラーチェック後に遅延を使用せずにリソースを閉じようとすると、コードにリスクが生じる可能性があります。

  • Example Without defer
file, err := os.Open(fileName) if err != nil { return err // Handle error } // Risk: If something goes wrong before this point, the file might never be closed // Additional operations here... file.Close() // Attempt to close the file later
ログイン後にコピー

Not using defer to close resources in Go can lead to unintended consequences, such as attempting to close a resource that was never successfully opened, resulting in unexpected behavior or panics. Additionally, if an error occurs before the explicit Close() call, the resource might remain open, causing leaks and exhausting system resources. As the code becomes more complex, ensuring all resources are properly closed becomes increasingly difficult, raising the likelihood of overlooking a close operation.

11. Risk of Using defer Before Checking if a File Was Opened

In Go, it's crucial to place a defer statement after verifying that a resource, like a file, was successfully opened.
Placing defer before the error check can introduce several risks and undesirable behavior.

Example of Incorrect Usage

file, err := os.Open(fileName) defer file.Close() // Incorrect: This should be deferred after the error check if err != nil { return err // Handle error } // Additional operations here...
ログイン後にコピー

Placing defer file.Close() before checking if os.Open succeeded can cause several issues. If the file wasn't opened and is nil, attempting to close it will lead to a runtime panic since Go executes all deferred functions even when an error occurs. This approach also makes the code misleading, implying that the file was successfully opened when it might not have been, which complicates understanding and maintenance. Furthermore, if a panic does occur, debugging becomes more challenging, especially in complex codebases, as tracing the issue back to the misplaced defer can take additional effort.

12. Conclusion

The defer keyword in Go simplifies resource management and enhances code clarity by ensuring that cleanup actions are performed automatically when a function exits. By using defer in these common scenarios, you can write more robust, maintainable, and error-free code.

以上がGo での defer の使用: ベスト プラクティスと一般的な使用例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!