例外-悪い運命


導入


あなたは、例外についてすべて聞きました.それらはほとんどの最新のOOP言語のエラー処理の基礎です.例はJava、JS、C +です.しかし、彼らは私たちに提示されるようにフレンドリーですか?この記事を見てみましょう.

例外の由来


例外のアイディアは1960年から70年代にかけて、Lispの初期の実装において始まりました.特にLISP 1.5では、Ferrble関数がファライブルコードの制御実行に使われました.後のLISPバージョンはこの考えの上に構築されました.しかし、その時点では、すでに他のプログラミング言語もそれを実装し始めていた.

最新のプログラミング言語における例外


Java、C++ C、C等の例外は、既定またはカスタムの例外クラスを使用して表されます.これは非常に簡単で安価な(生産性の面で)エラー処理パターンを可能にするが、それは人々が言うように良いですか?

例外の批評


このエラー処理パターンには多くの批判がありますが、いくつかの最も重要なものを指摘しましょう.
  • NO - OP例外ハンドラ.私がこれを意味するのは、強制例外チェックの目的のためだけに作られる例外ハンドラです.この動作の例は次のようになります.
  • try {
      code_that_might_fail();
    }
    catch(Exception e) { // no code here }
    
    彼らはあなたがそれらの2、3回、それらを使用する場合はあまりにも悪いですが、一度コードベースが大きくなると、プログラムを読むのが難しくなります.Javaは、すべての可能な例外ポイントを処理することを強制し、それが責任になるので、しばらくの間Javaを書いた後、より明らかになります.
  • 前の点から開発すると、IDEなしですべての例外をキャッチするのは難しいです.あなたが本格的なIDEを使用していない場合、またはVimやEmacsのような単純な何かを使用している場合は、コンパイル時やランタイムクラッシュの結果、開発時間が増加します.
  • バイナリサイズ肥大.説明の必要がほとんどない非常に単純なポイント.現代の例外処理は、アーキテクチャに固有ではありません.その結果、バイナリがBloatedになる原因となります.たとえば、あなたがWebサーバーを書いているときに問題ではありませんが、オペレーティングシステムとしての低レベル、またはドライバとして何かを書くとき、本当の問題になることができます.
  • でも。エラーをするより良い方法はありますか?


    答えは・・・可能性が高い!例外の選択肢の一つはエラー値です.通常はCでは非常に粗野な方法で実装されています.通常は関数からNULLを返すことです.いくつかの現代のプログラミング言語はこの考えを拡張します.2最も顕著な例はGoとZigです.

    試み


    Go スタティック型、コンパイル済みプログラミング言語です.他のデザイン決定の中で、GOチームは例外の代わりにエラー値を使用することを決めました.これの前に、GoogleはC +コードで例外の使用を禁止しました.goのエラーをチェックする方法は次のようになります.
    val, err := function_that_might_fail()
    if err != nil {
      print("Unfortunately our production servers are burning")
    } // the error handling part, nil being the null value in Go
    
    GOのエラー処理を見ることができますので、本当に簡単です、それはすべての例外処理の上記の問題を修正します.内部でエラー値を表現するのは簡単です(問題3を修正します).エラーを処理するのは簡単です(問題1、2を修正します).良い例は次のようになります.
    val, _ = function_that_might_fail_but_itsfine()
    // no error check, Go compiler and the Runtime does not complain
    // even if the function returns an error
    
    また、範囲の終わりに文の実行を置くDeferキーワードを紹介します.これは、任意のリソースを開いて、エラーをチェックした場合、両方のブランチでリソースを閉じる必要がないことを意味します.例:
    file, err := open_file_posix_is_cool(999)
    if err != nil {
       print("Logging to our super secret database")
       return err
    }
    defer close_file_posix_is_cool(file)
    
    file2, err := open_file_posix_is_cool(998)
    if err != nil {
       print("Logging to our super secret database")
       return err
    }
    defer close_file_posix_is_cool(file2)
    
    file3, err := open_file_posix_is_cool(2048)
    if err != nil {
       print("Logging to our super secret database")
       return err
    }
    defer close_file_posix_is_cool(file3)
    
    // resources are going to be properly cleaned up even if an error in one of the branches would occur
    

    ジグ


    Zig アンドリューケリーによって設計された命令型、汎用型、静的型、コンパイルされたシステムプログラミング言語です.ZIGエラー値はgoの値と非常に似ていますが、いくつかの方法で異なります.ZIGはまた、エラーセットのための徹底的なswitch文を紹介します、そして、トライとキャッチのようなキーワード(C +でのtry/catchと混同されないように、Java).tryキーワードは、指定した式がエラーになったかどうかを調べます.catchキーワードは、指定した式からエラーが評価された場合に実行されるコードを与えるために使用されます.

    概要


    物事を包むためには、導入で与えられた質問に答えましょう.この記事から、我々は答えはノーであることを学びました.しかし、我々はまた、別のエラー処理方法を発見し、どのように例外の欠点を解決する方法を示した.

    関連、引用と更なる読書

  • https://go.dev/
  • https://ziglang.org/
  • http://www.softwarepreservation.org/projects/LISP/MIT/White-NIL_A_Perspective-1979.pdf
  • https://en.wikipedia.org/wiki/Exception_handling
  • https://pixabay.com/vectors/error-warning-computer-crash-6641731/