エラーコードでプログラムを終了する慣用的な方法は何ですか?
Exit
のドキュメントには、「プログラムはすぐに終了します。遅延関数は実行されません。」と書かれており、_log.Fatal
_はExit
を呼び出します。凶悪なエラーではないものについては、遅延関数を実行せずにプログラムを終了すると極端に思えます。
エラーが発生したことを示すいくつかの状態を渡して、すべての遅延関数が実行された状態で安全に終了できることがわかっている時点でExit(1)
を呼び出しますか?
実際のmain
パッケージのほとんどでこれらの行に沿って何かをするので、return err
慣習はできるだけ早く採用され、適切に終了します。
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
func run() error {
err := something()
if err != nil {
return err
}
// etc
}
Fasで述べたように、osパッケージのfunc Exit(exitcode int)
があります。
ただし、遅延関数を適用する必要がある場合は、次のようにdefer
キーワードをいつでも使用できます。
http://play.golang.org/p/U-hAS88Ug4
すべての操作を実行し、エラー変数に影響を与え、最後にすべてがクリーンアップされたら、安全に終了できます。
そうでない場合は、panic/recoverを使用することもできます。 http://play.golang.org/p/903e76GnQ-
エラーが発生すると、パニックに陥り、クリーンアップを終了して、それをキャッチ(回復)します。
python私はよく行くパターンを次のように変換します:
func run() int {
// here goes
// the code
return 1
}
func main() {
os.Exit(run())
}
これを行う最も明確な方法は、exitCode
の先頭にmain
を設定し、次のステップとしてdefer
を閉じることだと思います。これにより、exitCode
の任意の場所でmain
を変更でき、最後の値は次のように終了します。
package main
import (
"fmt"
"os"
)
func main() {
exitCode := 0
defer func() { os.Exit(exitCode) }()
// Do whatever, including deferring more functions
defer func() {
fmt.Printf("Do some cleanup\n")
}()
func() {
fmt.Printf("Do some work\n")
}()
// But let's say something went wrong
exitCode = 1
// Do even more work/cleanup if you want
// At the end, os.Exit will be called with the last value of exitCode
}
出力:
Do some work
Do some cleanup
Program exited: status 1.
遊び場に行く https://play.golang.org/p/AMUR4m_A9Dw
これの重要な欠点は、エラーコードを設定した直後にプロセスを終了しないことです。