ホームページ >バックエンド開発 >Golang >Go の `log.Fatalln()` 呼び出しの後に `defer` 関数が実行されますか?

Go の `log.Fatalln()` 呼び出しの後に `defer` 関数が実行されますか?

Barbara Streisand
Barbara Streisandオリジナル
2024-12-07 19:44:14434ブラウズ

Will `defer` functions execute after a `log.Fatalln()` call in Go?

遅延関数と log.Fatalln() 呼び出し

問題:

次の Go コードを考えてみましょう:

db, err := sql.Open("postgres", "…")
if err != nil {
    log.Fatalln(err)
}
defer db.Close()

tpl, err := template.ParseGlob("")
if err != nil {
    log.Fatalln(err)
}

template.ParseGlob("") が返された場合エラーです。db.Close() 関数は呼び出されますか?

答え:

いいえ、このシナリオでは遅延関数は実行されません。

説明:

log.Fatalln() はエラーメッセージを出力し、os.Exit(1) を呼び出してプログラムをただちに終了するログ関数。内訳は次のとおりです。

  • log.Fatalln() は、log.Print() の後に os.Exit(1) が続くものと同等です。
  • os.Exit() により、プログラムは指定されたステータス コード (この場合、失敗の場合は 1) で終了します。
  • 遅延関数 (db.Close() など) は次のとおりです。 os.Exit() が呼び出されたときは実行されません。

コード スニペットでは、template.ParseGlob("") への呼び出しが失敗し、log.Fatalln() がトリガーされた場合、プログラムは終了します。すぐに。その結果、遅延関数 db.Close() は実行されず、データベース接続が開いたままになる可能性があります。

デモ:

この動作を説明するには、次のコードを実行できます:

package main

import (
    "log"
    "os"
)

func main() {
    defer os.Exit(1) // Exit the program with status code 1
    log.Fatalln("Program terminated early")
}

このコードを実行すると、エラー メッセージが記録され、プログラムが実行されます。遅延関数が実行されることなく、ただちに終了します。

回避策:

不適切に閉じられたリソースまたは未処理のタスクの問題を回避するには、エラーに対して log.Println() を使用することを検討してください。プログラムを終了せずにエラーをログに記録し、適切に処理します。

以上がGo の `log.Fatalln()` 呼び出しの後に `defer` 関数が実行されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。