Ruby 有两种不同的异常机制:投掷/接住和举起/救援。

为什么我们有两个?

什么时候应该使用其中一种而不是另一种?

有帮助吗?

解决方案

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

catch/ throw 与 raise/rescue 不同。catch / throw允许您快速退出块回到为特定符号定义catch的点,引发救援是涉及Exception对象的真正异常处理内容。

其他提示

  • raise, fail, rescue, , 和 ensure 处理 错误, ,也称为 例外情况
  • throwcatch控制流

与其他语言不同,Ruby's的投掷和捕获不用于例外。相反,当不需要进一步的工作时,它们提供了一种尽早终止执行的方法。(格林,2011)

终止单个级别的控制流,例如 while 循环,可以用一个简单的方法来完成 return. 。终止多个级别的控制流(例如嵌套循环)可以通过以下方式完成 throw.

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

参考

  1. 格林,阿夫迪。“投掷,捕捉,举起,救援……我很困惑!” RubyLearning博客。N.p.,2011 年 7 月 11 日。网络。1 月 1 日2012年。 http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. 托马斯、戴夫和安德鲁·亨特。“编程Ruby。” :实用程序员指南。N.p.,2001 年。网络。9 月 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 是最接近的类似物 throw/catch 从其他语言(或 Python 的 raise/except)。如果您遇到错误情况并且您会 throw 用另一种语言来代替它,你应该 raise 在红宝石中。

  2. 红宝石的 throw/catch 让你中断执行并爬上堆栈寻找 catch (喜欢 raise/rescue 确实如此),但并不真正意味着错误情况。它应该很少使用,并且只是在“沿着堆栈向上走直到找到相应的 catch“行为对于您正在编写的算法来说是有意义的,但考虑到 throw 对应于错误条件。

    Ruby 中 catch 和 throw 的用途是什么? 提供了一些关于良好使用的建议 throw/catch 构造。

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

  • rescue Foo 将拯救实例 Foo 包括子类 Foo. catch(foo) 只会抓住 同一个物体, Foo. 。不但过不了 catch 一个类名来捕获它的实例,但它甚至不会进行相等比较。例如

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

    会给你一个 UncaughtThrowError: uncaught throw "foo" (或一个 ArgumentError 在 2.2 之前的 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}, ,永远不会捕获任何东西,也不应该使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top