例外処理が悪いのはなぜですか?


89

GoogleのGo言語には設計上の選択として例外はありません。Linuxの名声のLinusは例外を駄目と呼んでいます。どうして?


2
ZeroMQの作成者は、C ++でそれを書くのは間違いだと彼がどう思ったかについて書いています(主にエラー処理のため)250bpm.com/blog:4
serbaut

Goには例外はないかもしれませんが、(遅延ステートメントがまだ実行されている間)から「回復」でき、非ローカル制御フローを提供する「パニック」があります...
Kerrek SB

ここで素晴らしい記事だlighterra.com/papers/exceptionsharmful(例外は有害考慮取り扱い)
masterxilo

Afaics、例外は、重要なボイラープレートを使用してGoでシミュレートできますが、この点は、ボイラープレートを手動で作成するよりも、構文糖からトランスパイルする方が意味がある場合があります。
シェルビームーアIII

回答:


81

例外を使用すると、例外がスローされて不変条件が壊れ、オブジェクトが不整合な状態になるコードを簡単に記述できます。それらは基本的にあなたが作るほとんどすべてのステートメントが潜在的に投げることができることを覚えて、それを正しく処理することを強制します。そうすることはトリッキーで直観に反することがあります。

簡単な例として、次のようなものを考えてみましょう。

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

仮定するFrobManagerだろう、このルックスOK、右?または、多分そうではない...か、または例外がスローされた場合を想像してみてください。この例では、の増分はロールバックされません。したがって、このインスタンスを使用している人は誰でもdeleteFrobObjectFrobManager::HandleFrob()operator newm_NumberOfFrobsFrobberしているユーザーは、オブジェクトが破損している可能性があります。

この例はばかげているように見えるかもしれません(そう、私は少し伸ばして1つを作成しなければなりませんでした:-))。しかし、重要なのは、プログラマーが例外を常に考えておらず、状態のすべての順列が確実にロールされるようにすることです。スローがあるときはいつでも、あなたはこのようにトラブルに巻き込まれます。

例として、ミューテックスと同じように考えることができます。クリティカルセクション内では、いくつかのステートメントを使用して、データ構造が破損していないこと、および他のスレッドが中間値を認識できないことを確認します。これらのステートメントのいずれかがランダムに実行されない場合、苦痛の世界に陥ります。次に、ロックと並行性を取り除き、そのような各メソッドについて考えます。可能であれば、各メソッドをオブジェクト状態の順列のトランザクションと考えてください。メソッド呼び出しの開始時に、オブジェクトはクリーンな状態であり、最後にクリーンな状態である必要があります。その間、変数fooは以下と矛盾する可能性がありますbar、しかしあなたのコードは最終的にそれを修正します。例外とは、ステートメントのいずれかがいつでもユーザーに割り込む可能性があるということです。責任は個々のメソッドごとにあなたにあり、それを正しくしてそれが起こったときにロールバックするか、スローがオブジェクトの状態に影響しないように操作を順序付けます。あなたがそれを間違えた場合(そしてこの種の間違いを犯しがちです)、呼び出し元は中間値を見ることになります。

RAIIのようなメソッドは、C ++プログラマーがこの問題の究極の解決策として言及するのが大好きで、これから保護するための長い道のりです。しかし、それらは特効薬ではありません。スローでリソースを確実に解放しますが、オブジェクトの状態の破損や中間値を参照する呼び出し元について考える必要がなくなります。したがって、多くの人にとって、コーディングスタイルのフィアットにより、例外ないと言う方が簡単です。です。記述するコードの種類を制限すると、これらのバグを導入するのが難しくなります。そうしないと、間違いを犯しやすくなります。

C ++での例外安全なコーディングについての本はすべて書かれています。多くの専門家が間違っています。それが本当に複雑で、ニュアンスが非常に多い場合は、その機能を無視する必要があることを示す良い兆候かもしれません。:-)


9
興味深い答えですが、私のプログラミング経験には何も反映されていません。したがって、それはカルチャー固有(おそらくPythonなどよりもJavaまたはC ++での問題のほうが多い)またはドメイン固有のどちらかだと思います。
ddaa 2009年

39
try-catch-finallyパターンを使用してマネージ言語で記述された例外は、適切に記述されていれば無効な状態のままになることはありません。finallyブロックの実行が保証されているので、オブジェクトはそこで割り当て解除できます。残りはスコープ外の変数とガベージコレクションによって処理されます。
Robert Harvey、

7
@ddaa問題はPythonで間違いなく可能です。結果は通常、バグの再現が困難です。おそらく、あなたは特に細心の注意を払っているか、幸運でした。しかし、それはそれがC ++の問題であり、EHの不良による最も一般的なバグがメモリリークであるというのは正しいことです。リークは最も深刻な問題ではないことを強調しようとしました。@Robert GCはメモリリークを軽減しますが、マネージコードによってプログラマエラーから解放されるかどうかはわかりません。特に、誰かが言語の問題ではないと考えて例外の安全性に注意を払っていない場合、それは大きな兆候ではありません。
asveikau 2009年

4
@lzprgmr確かにあります:例外によってdiffを処理できます。diffでのエラーのタイプ。コード内の場所。接続エラーに対処するには再接続が必要になる場合がありますが、深くネストされた関数の途中ではありません。あなたはそれを接続マネージャか何かにバブリングしたいです。次に、戻り値を処理することで、1回の呼び出しごとにエラーを確認し、手動で(たとえば、接続リセットエラーが発生した場合は)泡立ちます。また、戻り値は、ネストされた呼び出しで積み重ね:FUNC3を返すことができます-1、func2のは戻り、FUNC3を呼び出し-2彼のエラーの場合、-1 FUNC3の、など。ために
abourget

3
私は反対票を投じていましたが、例外が見落とされたのはそのためです。ただし、私の意見では、ほとんどすべてのメソッドまたはコードの一部が失敗する可能性があります。戻り値を導入することで、各エラー条件を処理することはできません。エラーに関する情報が失われます。すべてのステートメントをチェックしてクリーンアップを行うことですべてを適切に同期できると考えると、コードが非常に複雑になります。複数のステートメントでエラーをキャッチし、GCされていない1つまたは2つのリソースをクリーンアップする方がはるかにクリーンです。
Maarten Bodewes 2014

50

Goに例外がない理由は、Go言語の設計に関するFAQで説明されています。

例外も同様です。例外の設計は数多く提案されていますが、それぞれの設計により、言語とランタイムが大幅に複雑になります。まさにその性質上、例外は関数にまたがっておそらくゴルーチンにまで及ぶ。それらは幅広い意味を持っています。彼らが図書館に及ぼす影響についても懸念があります。それらは、定義上、例外的でありながら、それらをサポートする他の言語での経験であり、ライブラリおよびインターフェースの仕様に大きな影響を与えることを示しています。一般的なエラーを特別な制御フローに変えてすべてのプログラマーに補正することを奨励することなく、本当に例外的なものにすることができる設計を見つけるとよいでしょう。

ジェネリックと同様に、例外は未解決の問題です。

言い換えれば、彼らはGoで例外をサポートする方法をまだ満足のいく方法で理解していません。彼らは例外自体が悪いと言っているのではありません。

更新-2012年5月

囲碁の設計者は、フェンスから降りてきました。彼らのFAQは今これを言っています:

例外を制御構造に結合すると、try-catch-finallyイディオムのように、コードが複雑になります。また、プログラマーに、ファイルを開くのに失敗したなどの通常のエラーが多すぎることを例外として示すように促す傾向もあります。

Goは別のアプローチをとります。単純なエラー処理の場合、Goの複数値の戻りにより、戻り値をオーバーロードせずにエラーを簡単に報告できます。Goの他の機能と相まって、標準的なエラータイプはエラー処理を快適にしますが、他の言語のエラー処理とはかなり異なります。

Goには、真に例外的な状態を通知して回復するための組み込み関数もいくつかあります。回復メカニズムは、エラーの後に破壊される関数の状態の一部としてのみ実行されます。これは、大惨事を処理するのに十分ですが、追加の制御構造を必要とせず、適切に使用すると、エラー処理コードがクリーンになります。

詳細については、遅延、パニック、および回復の記事を参照してください。

つまり、簡単に言えば、複数値の戻り値を使用すると、別の方法でそれを行うことができます。(とにかく、例外処理の形式があります。)


...そしてLinuxの名声のLinusは例外のがらくたと呼んでいます。

例外がくだらないとLinusが考える理由を知りたい場合は、そのトピックに関する彼の執筆を探すことが最善です。これまでに追跡した唯一のことは、C ++のいくつかの電子メールに埋め込まれているこの引用です

「C ++の例外処理全体が根本的に壊れています。カーネルでは特に壊れています。」

彼は特にC ++の例外について話しているのであって、一般的な例外について話しているのではないことに注意してください。(そして、C ++の例外に明らかに、正しく使用するのが難しいいくつかの問題があります。)

私の結論は、Linusは例外(一般的に)を「がらくた」とまったく呼んでいないということです!


30
FAQに載せて情報を隠してしまうと嫌いです。:)
フォイブライアンdの

7
Linusはその電子メールを「C ++は恐ろしい言語です」で始めることに注意してください。そして、彼がC ++とそれでプログラムすることを選択した人々の両方をどれほど嫌っているのかについては怒鳴り続けています。したがって、C ++に対する彼のやや偏った意見を考えると、C ++の例外についての彼の意見は信頼できるとは思えない。
Pharap、2014

1
@ Hi-Angel-私が引用したテキストが言うように:「プレーンなエラー処理のために、Goの複数値の戻りは戻り値をオーバーロードすることなくエラーを報告することを容易にします。」。それはそれが関連している方法です。いずれにせよ、私はGoデザイナーの理論的根拠を引用しています。議論したい場合は、>> them <<で議論してください。
Stephen C

1
@ Hi-Angel-私はそれらの段落を書きませんでした。引用しただけです。それらに問題がある場合は、おそらく著者に取り上げてください。理論的には、コンテキストとしてGo言語のチュートリアルを提供できたはずです。しかし、率直に言って、Goの用語を理解していない人は、GoのWebサイトにアクセスして、その意味を調べることができます。
Stephen C

1
"..結果は複雑なコードになります"ずっと前に、私は多くの文字列操作を伴うCプログラムを書きました。すべてのメソッドは、allocationg memoryであり、割り当てが成功したかどうかを確認しました。コードの大部分は割り当てをチェックするだけのようでした。複雑ではないですか?例外のあるC ++は、私にとって非常に役立ちました。
robsosno 2017年

29

例外はそれ自体悪いことではありませんが、例外が頻繁に発生することがわかっている場合は、パフォーマンスの点で高価になる可能性があります。

経験則では、例外は例外条件にフラグを立てる必要があり、プログラムフローの制御にはそれらを使用しないでください。


9
@Robert:「プログラムフローの制御のためにそれらを使用するべきではありません」、私はこのように考えていませんでした。私にとって新しい視点:P +1
okw

2
それはまた、本当に言語に依存します。たとえばJavaでプログラミングしている場合、例外を回避することは困難です。
Charles Salvia、

2
@Charles:ポイントは、バグ、システムの設定ミス、または不合理な入力を示す状況では例外が適切であることです。ほとんどのJavaライブラリの例外は、「通常のワークフロー」コードで回避できます。
Artelius 2009年

6
彼らは多くの費用をかける必要はありません。たとえば、実行時間がゼロの「試行」を実装し、スタックで検出された呼び出し元アドレスに基づいて、テーブル内の「スロー」ルックアップ例外ハンドラーを検索することができます...最大の理由は、使用例外はパフォーマンスとはまったく関係ありません。
asveikau 2009年

言い換える; 質問は、例外を一般的に使用すること、または例外をまったく使用しないことを明確に示唆しています(それらはがらくたであるか、言語でさえもありません)。あなたの答えは、例外がプログラム制御フローに使用されたときにパフォーマンスに悪い理由を示すだけです。
Maarten Bodewes 2014

26

「例外的な状況でのみ例外をスローする」には同意しません。一般的には真実ですが、それは誤解を招くものです。例外は、エラー状態(実行の失敗)です。

使用する言語に関係なく、Framework Design Guidelines:Conventions、Idioms and Patterns for Reusable .NET Libraries(2nd Edition)を入手してください。例外のスローに関する章にはピアはありません。初版からの引用(私の作品では2枚目):

  • エラーコードを返さないでください。
  • エラーコードは簡単に無視できます。
  • 例外は、フレームワークでエラーを報告する主要な手段です。
  • 経験則として、メソッドがその名前が示すことを実行しない場合は、メソッドレベルのエラーと見なされ、例外が発生します。
  • 可能であれば、通常の制御フローに例外を使用しないでください

例外の利点に関するメモのページがあります(APIの一貫性、エラー処理コードの場所の選択、堅牢性の向上など)。いくつかのパターン(Tester-Doer、Try-Parse)を含むパフォーマンスに関するセクションがあります。

例外と例外処理は悪くありません。他の機能と同様に、それらは誤用される可能性があります。


3
私はそれに同意しなければなりません。私は例外に反対しているわけではなく、その本は必携ですが、.NET開発とC#に偏っています。

3
私はこれが古くからあることを知っています。.NETタイプと* nixタイプの間に一般的なスタイルの不一致があるようだとコメントしたいだけです。私がLinux開発者として使用したすべてのライブラリーは戻りコードを使用し、私が読んだ* nixスタイルのガイド(例えば、私の会社やGoogleのような)は単に「例外はありません」と言っています。面白いと思ってください。
jarvisteve 14

1
フレームワークは、例外をエンドユーザーアプリケーションとは異なる方法で処理する必要があります。フレームワークには、例外をスローする以外のエラーを処理する方法がありません。
0x6C38

11

golangの観点からは、例外処理がないことで、コンパイルプロセスがシンプルかつ安全に保たれると思います。

Linusの観点から見ると、カーネルコードはすべての場合に当てはまることを理解しています。したがって、例外を拒否することは理にかなっています。

現在のタスクをフロアにドロップしても問題がなく、エラー処理よりも一般的なケースのコードの方が重要である場合、例外はコードで理にかなっています。ただし、コンパイラからコードを生成する必要があります。

たとえば、Webやデスクトップアプリケーションのコードなど、ほとんどの高レベルのユーザー向けコードでは問題ありません。


しかし、カーネルコードに当てはまることは、長時間実行されるネイティブサーバープロセスにも当てはまります。
Lothar 2015

11

例外自体は「悪い」ものではありません。それは、例外がしばしば処理される方法であり、悪い傾向があります。これらの問題のいくつかを軽減するために例外を処理するときに適用できるいくつかのガイドラインがあります。これらの一部が含まれます(ただし、これらに限定されません)。

  1. 例外を使用してプログラムフローを制御しないでください。つまり、「catch」ステートメントに依存してロジックのフローを変更しないでください。これは、ロジックの周りのさまざまな詳細を隠す傾向があるだけでなく、パフォーマンスの低下につながる可能性があります。
  2. 返された「ステータス」が理にかなっている場合は、関数内から例外をスローしないでください。例外的な状況でのみ例外をスローしてください。例外の作成は、コストがかかり、パフォーマンスを集中的に使用する操作です。たとえば、メソッドを呼び出してファイルを開き、そのファイルが存在しない場合は、「FileNotFound」例外をスローします。顧客アカウントが存在するかどうかを判別するメソッドを呼び出してブール値を返す場合は、「CustomerNotFound」例外を返さないでください。
  3. 例外を処理するかどうかを決定するときは、例外に対して何か役立つことができる場合を除いて、「try ... catch」句を使用しないでください。例外を処理できない場合は、呼び出しスタックをバブルアップさせるだけです。そうしないと、例外がハンドラーによって「飲み込まれ」、詳細が失われる可能性があります(例外を再スローしない限り)。

2
ステータスを返すのは注意が必要です。GetCustomerメソッドが成功するとCustomerエンティティを返し、失敗するとnullを返すコードが多すぎます。複数のケースで、呼び出し元のコードは結果を確認しませんでしたが、すぐに顧客にアクセスしました。これはほとんどの時間で機能しました...
TrueWillの

3
ただし、GetCustomerがnullを返す代わりに例外をスローする場合でも、クライアントコードは例外を処理する必要があります。それがnullのチェックによるものであれ、例外の処理によるものであれ、責任はクライアントコードにあります。適切な処理を行わない場合、遅かれ早かれ何かが爆発します。
Chris、

1
@TrueWillテンプレート/ジェネリックをサポートする言語Option<T>は、null現在ではなくを返すことでこれを解決します。たとえば、Java 8で導入されたばかりで、Guava(およびその他)からヒントを得ています。
Maarten Bodewes 2014

@owlsteadうん。多分モナドが大好きです。あなたの言語がそれをサポートし、パターンマッチングを提供しているなら、それは良い方法です。
TrueWill、2014年

@owlstead再び、クリスが言ったことはまだそのために強力です-ユーザーは.orElse(defaultObject)関数、または問題の言語が決定したイディオムを呼び出すことを忘れないでください。結局のところ、問題を処理しているのは、エラー処理方法ではなく、最終的にはプログラマーです。
Pharap、2014

9

典型的な引数は、特定のコード(言語によって異なります)からどの例外が発生するかを知る方法がないこと、およびgotosに非常に似ているため、実行を精神的に追跡することが困難であるというものです。

http://www.joelonsoftware.com/items/2003/10/13.html

この問題については、コンセンサスはありません。LinusのようなハードコアCプログラマーの観点からは、例外は間違いなく悪い考えだと思います。ただし、典型的なJavaプログラマーは状況が大きく異なります。


1
Cコードには例外があります。自明ではない関数へのすべての呼び出しをifsでラップする必要があるため、その言語の使用は頭痛の種です!
RCIX、2009年

1
setjmp/ もありlongjmp、これはかなり悪いです。
Tim Sylvester、

9
ダクトテーププログラマーを大事にし、ユニットテストが必要だとは思わない人のアドバイスを本当に受けたいですか?joelonsoftware.com/items/2009/09/23.html
TrueWill

4
これは、主題に関する議論が人格の参照に置き換えられる議論における古典的な間違い(またはチート)です。これは通常、議論が悪化している兆候です。
Petr Gladkikh 2012

1
@PetrGladkikh議論はOPからLinusの意見に言及して始まりました...そのチートは権威への訴えの誤りとして知られています。議論はそこから上るだけで、Linusが彼の個性を参照してなぜ例外が好きではないのかという質問に答えることは「チート」ではありません。
ジムバルター、2012

7

例外は悪くありません。これらは、C ++の最もエレガントなC ++のRAIIモデルにうまく適合します。例外安全ではないコードの束がすでにある場合、それらはそのコンテキストでは良くありません。Linux OSのような本当に低レベルのソフトウェアを書いているなら、それは悪いことです。一連のエラー戻りチェックでコードを散らかしたい場合は、役に立ちません。例外がスローされたときにリソース制御の計画がない場合(C ++デストラクタが提供するもの)は、問題があります。


7
RAIIは例外なく役立ちます。
Mark Ransom、

4
ただし、例外はRAII(またはその他の自動リソース管理)なしでは役に立ちません。
グレッグロジャース

+1は、例外が適切ではなく、例外が本質的に悪いわけではない状況を指摘します。
Pharap、2014

4

したがって、例外の優れたユースケースは...

あなたがプロジェクトにいて、すべてのコントローラー(約20の異なる主要なコントローラー)がアクションメソッドで単一のスーパークラスコントローラーを拡張するとします。次に、すべてのコントローラが、オブジェクトB、C、Dを呼び出す場合と、F、G、Dを呼び出す場合とで、互いに異なる処理を実行します。大量の戻りコードがあり、すべてのコントローラーが異なる方法で処理していた多くの場合、ここで例外が役立ちます。私はそのすべてのコードを破壊し、「D」から適切な例外をスローし、それをスーパークラスのコントローラーアクションメソッドでキャッチしました。これで、すべてのコントローラーが一貫しています。以前は、Dはエンドユーザーに伝えたいが、できなかった複数の異なるエラーケースに対してnullを返していましたが、私はしませんでした

はい、各レベルとリソースのクリーンアップ/リークを心配する必要がありますが、通常、どのコントローラーにもクリーンアップするリソースがありません。

私たちに例外があったら神に感謝します。そうでなければ、私は巨大なリファクタリングに参加し、単純なプログラミング問題であるはずの何かに多くの時間を浪費していました。


1
+1私が読んだ例外を使用するための最良の議論の1つです。より詳細な例(つまり、UMLダイアグラム、いくつかの疑似コード、または実際のコード)を使用することもできますが、サブクラスを一貫して実行することに関するポイントは良いものです。また、証拠が逸話的であるという事実は、例外が実際の状況で有用であり、有用性が言語機能の主な目的であることを示しています。
Pharap、2014

ちょうど追加として、あなたがスカラの場合、代わりに例外または実際の応答を表すTry [ResponseType]を返すことができます。その後、私が上で触れたのと同じパターンに従って、実際に実行する以外の例外はありません。それからあなたが持っているすべてのメソッドが私が必要だと思う1 + nの応答タイプを返すようです。ただし、私たちのscalaは、Tryと同じように機能しますが、より非同期のプログラミングに役立つFuture [response]を返します。
ディーンヒラー

2

理論的には、彼らは本当に悪いです。完璧な数学の世界では、例外的な状況に陥ることはありません。関数型言語を見てください。これらには副作用がないため、例外的な状況のソースは事実上ありません。

しかし、現実は別の話です。私たちは常に「予期しない」状況を抱えています。これが例外が必要な理由です。

例外はExceptionSituationObserverの構文シュガーとして考えることができると思います。例外の通知を受け取るだけです。これ以上何もない。

Goを使用すると、「予期しない」状況に対処する方法が紹介されると思います。彼らはそれを例外として、そしてアプリケーションロジックとしてより破壊的に聞こえないようにしようとすることを推測することができます。しかし、これは私の推測です。


2
「関数型言語を見ると、副作用がないので、例外的な状況のソースは事実上ありません。」それはひどい誇張です。
スティーブンC

3
数学の5/0は何ですか?アルクシン(200)?Sqrt(-1)?数学には例外的な状況がたくさんあります。
Robert Fraser

3
これは例外的な状況ではありません...それらには意味がありません...そしてそれが例外として実装される可能性があるためです...しかし、前提条件のバイアル化として実装される可能性もあります..それは技術的な実装に依存します。
Mike Chaliy、

3
@MikeChaliy-申し訳ありませんが、それは単なる洗練されたものです。あなたはそのような推論を適用して、何にも例外的な状況は決してない、と言うことができます。実際には、意味を持たない(または明確な値を持たない)数式は例外的です。これは、例外をスローしてキャッチすることでそれらを処理する必要があることを意味するわけではありませんが、そうしないと、特別な値(InfやNanなど)または複数の値を返す演算が必要になります。要するに、これらの場合、一種の特別な扱いが必要です
スティーブンC

1
コンピュータは状態機械です。完璧な数学の世界ではありません。
Arunav Sanyal 2016

1

C ++の例外処理パラダイムは、Javaの部分的な基礎を形成し、次に.netにもいくつかの優れた概念が導入されていますが、いくつかの厳しい制限もあります。例外処理の主要な設計意図の1つは、メソッドが後条件を満たしているか例外をスローすることを確実にし、メソッドが終了する前に行う必要があるクリーンアップが確実に行われるようにすることです。残念ながら、C ++、Java、および.netの例外処理パラダイムはすべて、予期しない要因によって予期されるクリーンアップが実行されない状況を処理するための適切な手段を提供できません。これは、予期しない事態が発生した場合にすべてが突然停止するリスクを負わなければならないことを意味します(スタックの巻き戻し中に例外を処理するC ++のアプローチが発生します)。

例外処理が一般的に適切であるとしても、他の問題の後にクリーンアップするときに発生する問題を処理するための適切な手段を提供できない例外処理パラダイムを許容できないと見なすことは不合理ではありません。つまり、フレームワークは、複数の障害が発生した場合でも適切な動作を保証できる例外処理パラダイムを使用して設計できなかったというわけではありませんが、トップの言語やフレームワークはまだそうすることができません。


1

私は他のすべての答えを読んだことがないので、これについてはすでに言及しましたが、1つの批判として、プログラムが長いチェーンで中断され、コードのデバッグ時にエラーを追跡することが難しくなります。たとえば、Foo()がToString()を呼び出すWah()を呼び出すBar()を呼び出すと、誤って誤ったデータがToString()にプッシュされ、Foo()のエラーのように見えます。


0
  • 例外が処理されないのは、一般的に悪いことです。
  • 例外処理が不適切です(もちろん)。
  • 例外処理の「良い点/悪い点」は、それを行うためではなく、コンテキスト/スコープと適切さに依存します。

0

さて、ここで退屈な答え。それは本当に言語に依存すると思います。例外によって割り当てられたリソースが残される可能性がある場合は、それらを回避する必要があります。スクリプト言語では、アプリケーションフローの一部を単に破棄またはジャンプします。それ自体は嫌いですが、致命的なエラーを例外で回避することは許容できる考えです。

エラー信号については、私は一般的にエラー信号を好みます。すべては、API、ユースケースと重大度、またはロギングで十分かどうかに依存します。また、私はその振る舞いを再定義しようとしていますthrow Phonebooks()。「例外」はしばしば行き止まりであるという考えですが、「電話帳」には、エラー回復または代替の実行ルートに関する役立つ情報が含まれています。(良いユースケースはまだ見つかりませんが、引き続き試してください。)


0

私にとって、問題は非常に簡単です。多くのプログラマは例外ハンドラを不適切に使用しています。言語リソースが多いほど良いです。例外を処理できるようにするのは良いことです。不正使用の1つの例は、検証されない整数でなければならない値、または除算され、ゼロの除算がチェックされない可能性のある別の入力です...例外処理は、より多くの作業とハードな思考を回避する簡単な方法かもしれません汚いショートカットを作成して例外処理を適用したい場合があります...アルゴリズムによって処理された問題の一部がその性質上不明確である場合、「プロのコードは決して失敗しない」というステートメントは幻想かもしれません。おそらく、本質的に未知の状況では、例外ハンドラーが役立ちます。良いプログラミングの実践は議論の問題です。


問題は、コードが失敗するかどうかではありません(または、そうすべきではありません)。より大きな問題は、コードが失敗した場合に、詳細に注意する範囲です。ドキュメントを読み込もうとして「データを読み取る」メソッドの1つが失敗した場合、効果は同じでドキュメントが読み込めないため、どれが実際にどれを気にすることもありません。概念的には、例外処理はそれに適しているはずです。問題は、.NETとJavaの例外処理パラダイムでは、一括して処理する必要のある「退屈な」例外と、そうでない場合の例外を区別する優れた方法が提供されていないことです。
スーパーキャット2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.