在Ruby中提高异常与抛出异常有什么区别?

时间:2008-09-09 00:41:03

标签: ruby exception

Ruby有两种不同的异常机制:Throw / Catch和Raise / Rescue。

为什么我们有两个?

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

3 个答案:

答案 0 :(得分:100)

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

  捕获/抛出与加注/救援不同。 catch / throw允许您快速将块退出到为特定符号定义catch的点,raise rescue是涉及Exception对象的真正异常处理。

答案 1 :(得分:95)

  • raisefailrescueensure处理错误,也称为例外
  • throwcatch控制流程
  

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

终止单一级别的控制流,如while循环,可以使用简单的return来完成。终止许多级别的控制流,如嵌套循环,可以使用throw完成。

  

虽然提升和救援的异常机制非常适合在出现问题时放弃执行,但在正常处理期间能够跳出一些深度嵌套的构造有时会很好。这就是捕获和投掷派上用场的地方。   (托马斯和亨特,2001年)

参考

  1. 格林,Avdi。 "投掷,抓住,提升,救援......我很困惑!" RubyLearning博客。 N.p.,2011年7月11日。网站。 2012年1月1日。http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/
  2. Thomas,Dave和Andrew Hunt。 "编程Ruby。" :务实的程序员指南。 N.p.,2001。Web。 2015年9月29日。http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html

答案 2 :(得分:18)

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

  1. raise / rescue是您与其他语言(或Python&#)熟悉的throw / catch构造最接近的类似物39; s raise / except)。如果您遇到错误情况,并且用另一种语言throw覆盖它,则应该在Ruby中raise

  2. Ruby throw / catch可让您中断执行并爬上堆栈,寻找catch(如raise / {{1但是,并不是真正意味着错误的条件。它应该很少使用,并且只是当"走到堆栈直到找到相应的rescue"行为对于您正在编写的算法有意义,但将catch视为与错误条件相对应是没有意义的。

    What is catch and throw used for in Ruby?提供了有关throw / throw构造的良好用途的一些建议。

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

    • catch将拯救rescue Foo的实例,包括Foo的子类。 Foo只会抓取同一个对象catch(foo) 。你不仅不能通过Foo一个类名来捕获它的实例,而且它甚至不会进行相等比较。例如

      catch

      会在2.2之前的Ruby版本中为您提供catch("foo") do throw "foo" end (或UncaughtThrowError: uncaught throw "foo"

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

      ArgumentError

      多个begin do_something_error_prone rescue AParticularKindOfError # Insert heroism here. rescue write_to_error_log raise end es需要嵌套...

      catch
    • catch :foo do catch :bar do do_something_that_can_throw_foo_or_bar end end 相当于rescue,是一个惯用的构造。 A"裸rescue StandardError",如catch,永远不会抓到任何东西,不应该被使用。