Jar*_*eck 103
raise,fail,rescue,和ensure处理错误,也被称为异常throw并且catch是控制流程与其他语言不同,Ruby的throw和catch不用于异常.相反,它们提供了一种在不需要进一步工作时提前终止执行的方法.(格林,2011)
终止单级控制流,如while循环,可以通过简单的方式完成return.终止许多级别的控制流,如嵌套循环,可以完成throw.
虽然引发和救援的异常机制非常适合在出现问题时放弃执行,但有时候能够在正常处理期间跳出一些深度嵌套的构造是很好的.这就是捕获和投掷派上用场的地方.(Thomas和Hunt,2001)
Rea*_*nly 101
我认为http://hasno.info/ruby-gotchas-and-caveats对差异有一个不错的解释:
catch/throw与raise/rescue不同.catch/throw允许您快速退出块返回到为特定符号定义catch的点,raise rescue是涉及Exception对象的真正异常处理内容.
Mar*_*ery 19
https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise提供了一个很好的解释,我怀疑我可以改进.总结一下,在我去的时候从博客文章中删除一些代码示例:
raise/ rescue是与其他语言(或Python的/ )熟悉的throw/ catch构造最接近的类似物.如果你遇到了一个错误条件而你会用另一种语言覆盖它,你应该在Ruby中.raiseexceptthrowraise
Ruby's throw/ catch允许你打破执行并爬上堆栈寻找catch(喜欢raise/ rescue确实),但并不真正意味着错误条件.它应该很少使用,并且只是当"向上移动堆栈直到找到相应的catch"行为对于您正在编写的算法有意义但是将其throw视为对应于错误是没有意义的条件.
什么是Ruby中的catch和throw?提供了关于throw/ catchconstruct的良好用法的一些建议.
它们之间具体的行为差异包括:
rescue Foo将拯救Foo包含子类的实例Foo.catch(foo)只会抓住同一个对象Foo.您不仅不能传递catch类名来捕获它的实例,而且甚至不会进行相等比较.例如
catch("foo") do
  throw "foo"
end
会给你一个UncaughtThrowError: uncaught throw "foo"(或ArgumentError2.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},永远不会捕获任何东西,不应该使用.