186

Ruby には、Throw/Catch と Raise/Rescue という 2 つの異なる例外メカニズムがあります。

なぜ2つあるのですか?

一方を使用し、もう一方を使用しないのはいつですか?

4

3 に答える 3

125
  • raisefailrescue、およびensureハンドルエラー(例外とも呼ばれる)
  • throwcatch制御フローです

他の言語とは異なり、Ruby の throw と catch は例外に使用されません。代わりに、それ以上の作業が不要になったときに実行を早期に終了する方法を提供します。(グリム、2011)

ループのような単一レベルの制御フローを終了するにwhileは、単純なreturn. ネストされたループのように、多くのレベルの制御フローを終了するには、throw.

レイズとレスキューの例外メカニズムは、問題が発生したときに実行を放棄するのに最適ですが、通常の処理中に深くネストされた構造から飛び出すことができると便利な場合があります。ここでキャッチアンドスローが役に立ちます。(トーマスとハント、2001)

参考文献

  1. グリム、アヴディ。「投げて、捕まえて、上げて、助けて……混乱しちゃった!」RubyLearning ブログ。Np、2011 年 7 月 11 日。ウェブ。1 2012 年 1
  2. トーマス、デイブ、アンドリュー・ハント。「Rubyのプログラミング」: 実用的なプログラマーのガイド。Np、2001年。ウェブ。2015 年 9 月 29 日。http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html .
于 2012-01-01T06:18:28.930 に答える
112

http://hasno.info/ruby-gotchas-and-caeatsには、違いの適切な説明があると思います。

キャッチ/スローはレイズ/レスキューと同じではありません。キャッチ/スローを使用すると、特定のシンボルに対してキャッチが定義されているポイントまでブロックをすばやく終了できます。レイズ レスキューは、Exception オブジェクトに関連する実際の例外処理です。

于 2008-09-09T00:50:02.753 に答える
22

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raiseは、私が改善できるとは思えない優れた説明を提供しています。要約すると、ブログ投稿からいくつかのコード サンプルを抜粋します。

  1. raise/は、他の言語 (または Python の/ )で使い慣れた/コンストラクトrescueに最も近い類似物です。エラー状態に遭遇し、別の言語でそれを上書きする場合は、Ruby を使用する必要があります。throwcatchraiseexceptthrowraise

  2. Ruby のthrow/を使用すると、実行を中断して( /のように)catchを探してスタックを上ることができますが、実際にはエラー状態を想定したものではありません。これはめったに使用されるべきではなく、「対応するものが見つかるまでスタックを上る」動作が、作成しているアルゴリズムにとって意味があるが、エラーに対応すると考えるのは意味がない場合にのみ存在します。調子。catchraiserescuecatchthrow

    Rubyでキャッチアンドスローは何に使用されますか? throw/catchコンストラクトの適切な使用法についていくつかの提案を提供します。

それらの間の具体的な動作の違いは次のとおりです。

  • rescue FooFooのサブクラスを含むインスタンスをレスキューしますFooは同じオブジェクトcatch(foo)のみをキャッチします。クラス名を渡してそのインスタンスをキャッチできないだけでなく、等値比較もできません。例えばFoocatch

    catch("foo") do
      throw "foo"
    end
    

    UncaughtThrowError: uncaught throw "foo"(または2.2ArgumentErrorより前のバージョンの Ruby では)

  • 複数のレスキュー節をリストできます...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end
    

    複数のcatches をネストする必要がありますが...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • rescueは と同等でrescue StandardErrorあり、慣用的な構造です。のような「ベアcatch」は、catch() {throw :foo}何もキャッチしないため、使用しないでください。

于 2014-12-03T16:42:02.623 に答える