在Ruby中抛出exception与抛出exception有什么区别?

Ruby有两个不同的例外机制:抛出/捕获和提升/救援。

为什么我们有两个?

你应该什么时候使用一个,而不是另一个?

我认为http://hasno.info/ruby-gotchas-and-caveats有一个不错的解释:;

catch / throw与raise / rescue不一样。 catch / throw可以让你快速退出块,为特定的符号定义一个catch,raise rescue是真正的exception处理涉及Exception对象的东西。

  • raisefailrescue ,并ensure处理错误 ,也被称为例外
  • throwcatch控制stream

与其他语言不同,Ruby的throw和catch不用于例外。 相反,它们提供了一种在不需要进一步工作时提前终止执行的方法。 (格林,2011)

终止一个单一的控制stream程,就像一个while循环,可以通过一个简单的return来完成。 终止许多级别的控制stream,如嵌套循环,可以用throw来完成。

虽然在事情出错的时候,提升和救援的例外机制对于放弃执行来说是很好的,但是在正常的处理过程中能够跳出一些深度嵌套的构造有时是很好的。 这是捕捉和抛出派上用场的地方。 (Thomas和Hunt,2001)

参考

  1. 格林,Avdi。 “扔,抓,举,救…我很困惑! RubyLearning博客。 Np,2011年7月11日。 2012年1月1日。http ://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue-im-so-confused/ 。
  2. 托马斯,戴夫和安德鲁·亨特。 “Ruby编程”。 :实用程序员指南。 Np,2001. Web。 29九月2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise提供了一个很好的解释,我怀疑我可以改进。; 总而言之,在我去的时候,从博客文章中挑出一些代码示例:

  1. raise / rescue是与其他语言(或Python的raise / except )熟悉的throw / catch结构最相似的。 如果你遇到了错误情况,你会用另一种语言throw它,你应该用Ruby进行raise

  2. Ruby的throw / catch可以让你打破执行,爬上堆栈寻找catch (就像raise / rescue一样),但是并不是真正意义上的错误条件。 它应该很less使用,只是当“走上堆栈,直到find相应的catch ”的行为对于你正在编写的algorithm是有意义的,但是将throw看作对应于一个错误条件。

    什么是在Ruby中使用的catch和throw? 提供了一些关于throw / catch构造的很好用法的build议。

它们之间的具体行为差异包括:

  • rescue Foorescue Foo实例,包括Foo子类。 catch(foo)只会捕获同一个对象Foo 。 你不仅可以通过catch一个类名来捕获它的实例,它甚至不会进行相等的比较。 例如

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

    会给你一个UncaughtThrowError: uncaught throw "foo" (或者在2.2之前版本的Ruby中有一个ArgumentError

  • 多个救援条款可以列出…

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

    而多个catch需要嵌套…

     catch :foo do catch :bar do do_something_that_can_throw_foo_or_bar end end 
  • 裸露的rescue等同于rescue StandardError ,是一个惯用的构造。 像catch() {throw :foo}这样的“裸机”永远不会捕获任何东西,也不应该被使用。