いつos.Exit()とpanic()を使用するのですか?


92

Go の主な違いos.Exit()panic()、Goでの実際の使用方法について誰かが説明できますか?


11
将来のGoコードの読み取りに役立つと期待される単なるコメント:多くのサンプルコードでpanicは、エラーで終了するために使用されています。これは、それが良い、または慣用的な実践であるという意味ではありません!。これは、サンプルコードの単なるスペース節約デバイスです。非常に特殊な状況のpanicためのIRL予約。
Intermernet、2015

1
Hm..good)特に「IRL」の省略形-それは私にとって新しいものです:)パニックがパッケージのインポートをどのように排除するかを説明できますか?
Timur Fayzrakhmanov、2015

4
panic組み込みです。のようなものを使用すること(状況に応じて)をお勧めしますos.Exitlog.Fatal(可能な場合は常に推奨)OSにエラーコードを返しますなど、。これらはすべてパッケージのインポートを伴うため、サンプルコードが "乱雑"になります。コード例は常に、特定の問題の解決策を示すためにのみ使用する必要があります。コードに他の問題がある可能性があります。適切にデモンストレーションされた場合、コードがより複雑になり、そのため、与えられた回答の説明が損なわれます。YMMV。
Intermernet、2015

1
わかりました、それを理解しました!)大きな感謝)私の語彙にはさらに別の略語があるようです:)
Timur Fayzrakhmanov

2
NP、喜んでお手伝いし、頭字語の語彙を増やします:-)
Intermernet

回答:


84

まず、「実際にどのように使用するか」という質問がある場合は常に、Goソースコード(または実際には十分に大きなGoコードベース)とパッケージドキュメントで回答を検索することをお勧めします。

さて、os.Exitpanicはかなり異なっています。panicプログラムまたはその一部が回復不能な状態に達したときに使用されます。

ときにpanic、このような範囲外のスライスをインデックスや型アサーションの失敗など、実行時エラーのために暗黙的に含む、と呼ばれ、それはすぐに現在の関数の実行を停止し、道に沿って任意の繰延機能を実行し、ゴルーチンのスタックをアンワインド開始します。その巻き戻しがゴルーチンのスタックの最上部に到達すると、プログラムは終了します。

os.Exitすぐにプログラムを中止する必要がある場合に使用します。回復や遅延クリーンアップステートメントの実行の可能性はなく、エラーコードも返します(他のプログラムが発生したことを報告するために使用できます)。これはテストで役立ちます。この1つのテストが失敗した後、もう1つのテストも失敗することがすでにわかっている場合は、ここで終了することもできます。これは、プログラムが実行する必要があるすべてのことを行ったときにも使用でき、ヘルプメッセージを出力した後で終了する必要があります。

ほとんどの場合は使用せずpanicerror代わりに返す必要があります)、os.Exitテストやプログラムの迅速な終了のために、一部のケース以外ではほとんど必要ありません。


9
「これはテストで役立ちます。このテストの1つが失敗した後、もう1つも失敗することをすでに知っている場合は…」これは、依存テストのテストアンチパターンのにおいがします。適切に作成されたテストスイートでは、各テストは独立しています。特定のテストの結果によって、他のテストの結果が決まることはありません。
gotgenes

1
@gotgenes必ずしもそうではありません。特定の関数が非nil構造体を返すというテストがあり、そのテストが失敗した場合、構造体の値を調べるすべてのテストも失敗することを期待できます。依存するのはコードであり、テストではありません。(とは言っても、exitその場合は使用しません。アサーションの失敗が大量に発生すると予想します。)
David Moles

83

まず第一にos.Exit()、エラーなしでプログラムを正常に終了し、パニックしないために使用できるので、これは重要な違いの1つです。もう1つは、どこかでパニックが検出され、無視またはログに記録される可能性があることrecoverです。

しかし、誤った終了コードについて話している場合は、次のようにしましょう。

panic何かがひどくうまくいかない場合に使用します。おそらく、本番環境に移行する前にキャッチしておくべきプログラマーのエラーです。これがスタックを出力する理由です。

os.Exit(errorCode)あなたがしたいなら、そのようなものを使用してください:

  1. スクリプトの目的でプログラムの終了コードを制御します。

  2. 予期されるエラー(例えば、ユーザー入力エラー)で整然と終了したい。

だから基本的にパニックはあなたのためであり、悪い終了コードはあなたのユーザーのためです。


非常に役に立ちました!)
Timur Fayzrakhmanov

14
「基本的にパニックはあなたのためであり、悪い終了コードはユーザーのためです。」<-すばらしいヒント
psousa

1
panic()は通常のCでの通常のassert()呼び出しに何らかの形で関連していると言えるでしょうか?ええと、私は常に本番環境にプッシュする前にアサートコールを削除し、新しい機能をテストするときにのみ有効にすることを知っています。私が言っているのは、ほとんどの場合、assert()を使用して、コードで当てはまるはずだと思う不変条件を検証することです。panic()でも同じように見えますか?:-)
yves Baumes

7

主な違いは次のとおりです。

  1. os.Exit 据え置き関数の実行をスキップします。
  2. ではos.Exit、終了コードを指定できます。
  3. panicは終了しますが、終了しos.Exitません。(他の回答はこれについて言及していないようです。)

遅延関数を実行する必要がある場合は、他に選択肢はありませんpanic。(一方、据え置き関数の実行をスキップしたい場合は、を使用してくださいos.Exit。)

非void関数がこのように定義されている場合:

  1. 関数には多くのブランチが含まれています
  2. すべてのブランチはreturnまたはで終了しますpanic

その後panicos.Exit他の方法で置き換えることはできません。コンパイラは、「関数の最後でリターンがありません」と言ってプログラムのコンパイルを拒否します。(Goはここでは非常にばかげてlog.Panicいます。関数を終了することもありません。)

その他の条件下:

  1. panicプログラミングロジックエラーなど、実際に配線された何かが発生したときに使用します。
  2. os.Exit終了コードを指定して、すぐに終了する場合に使用します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.