web-dev-qa-db-ja.com

パニックを使用するかエラーを返す必要がありますか?

Goにはエラーを処理する2つの方法がありますが、どちらを使用するかはわかりません。

引数としてスライスまたはマップを受け入れる古典的なForEach関数を実装していると仮定します。反復可能オブジェクトが渡されるかどうかを確認するには、次のようにします。

_func ForEach(iterable interface{}, f interface{}) {
    if isNotIterable(iterable) {
        panic("Should pass in a slice or map!")
    }
}
_

または

_func ForEach(iterable interface{}, f interface{}) error {
    if isNotIterable(iterable) {
        return fmt.Errorf("Should pass in a slice or map!")
    }
}
_

panic()は避けるべきだという議論をいくつか見ましたが、人々は、プログラムがエラーから回復できない場合は、panic()をすべきだとも言っています。

どちらを使用すればよいですか?そして、正しいものを選ぶための主な原則は何ですか?

18
laike9m

From Dave Cheney

panicsは常にプログラムにとって致命的です。パニック状態では、発信者が問題を解決できるとは思いません。したがって、panicは例外的な状況、コードが不可能な状況、またはコードを統合している人が継続する場合にのみ使用されます。

パニックは、プログラム全体で、または少なくとも現在のゴルーチンですぐに致命的になると想定する必要があります。 「これが起こったら、アプリケーションをすぐにクラッシュさせるべきですか?」はいの場合、パニックを使用します。それ以外の場合は、エラーを使用します。

29
Adrian

panicを使用します。

あなたのユースケースは、APIの不適切な使用をキャッチするためです。プログラムがAPIを適切に呼び出している場合、実行時にこれが発生することはありません。

実際、正しい引数でAPIを呼び出すプログラムは同じ方法で動作しますテストが削除された場合。テストは、失敗したプログラマーに役立つエラーメッセージで早期に失敗するだけです。理想的には、テストスイートを実行している開発中にパニックに一度到達し、プログラマが悪いコードをコミットする前でも呼び出しを修正し、その誤った使用が本番に到達することはありません。

この応答 を参照してくださいGoのエラーを使用した関数パラメーターの検証は良いパターンですか?

4
dolmen

パニックとは、通常、何かが予想外に間違っていたことを意味します。通常、通常の操作中に発生してはならないエラー、または正常に処理する準備ができていないエラーで高速に失敗するために使用されます。したがって、この場合はエラーを返すだけで、プログラムがパニックに陥ることは望ましくありません。

0
user8067560

サービスの開始中に何らかの必須要件が提供されていない場合、または提供されていない場合(データベース接続、必要なサービス構成など)、パニックを使用する必要があります。

ユーザーの応答またはサーバー側のエラーには戻りエラーがあります。

0
Parmatma

次の質問を自問してください。

  • アプリのコーディングの程度にかかわらず、例外的な状況が発生すると予想していますか?アプリの通常の使用の一部として、ユーザーにそのような状態を知らせることは有益だと思いますか?アプリケーションが正常に動作していることに関係するため、エラーとして処理します。
  • 適切に(そしていくぶん防御的に)コーディングすれば、その例外的な状況は発生しませんか? (例:ゼロで除算するか、範囲外の配列要素にアクセスします)あなたのアプリはそのエラーの下で完全に無知ですか?パニック。
  • APIがあり、ユーザーが適切に使用できるようにしますか?パニック。誤って使用すると、APIはほとんど回復しません。
0
Luis Masuelli