ruby的throw语句接受任何Object,这意味着下面的任何一个都是合法的。

throw BasicObject
throw 123456.78
throw "wow"
throw :doge

然而,据我所知,我选择抛出Symbol有两个原因。
一个人必须catch与抛出的Object完全相同。这意味着执行catch "wow"将导致UncaughtThrowError。使用Symbols时这不是问题。
Object之后不能引用抛出的catch。要指定返回值,可以将其作为第二个参数输入:throw :doge, "wow"这将破坏在我看来抛出自定义Object的整个要点。
此外,令人困惑的是throw的(第一个)参数以前被限制在Symbols之前。这难道不意味着有人必须ruby 1.9非符号,而ruby必须改变他们的实现以允许这样的用例吗?或者是别的什么…比如为类型检查节省执行时间。
在这一点上,我能想象的除了throws之外的唯一东西是Symbols,但这是改变的原因吗?请启发我。

最佳答案

假设您正在使用某个库,而您并不关心它的内部。如果该库使用带有某个符号(或任何其他公共对象)的throw方法,而该符号(或对象)碰巧与您在自己的代码中使用的throw符号(或对象)相同,该怎么办?它会导致不必要的互动。另一方面,如果您创建一个自定义对象并抛出它,则不必关心此类问题。特别是如果您只将其定义为局部变量,它将是安全的。如果将其定义为常量,则相对安全(危险在于另一个库在相同的名称空间中意外使用了相同的常量名称)。
带有块参数的catch创建Object的实例,并将其作为块变量分配,这样就安全了。
当我使用throw时,我通常不能使用块变量形式,因为大多数情况下,我使用不同的方法throwcatch。因此,我创建了一个Object的实例,并将其分配为私有常量,这使得它相对安全。

class SomeClass
  Foo = Object.new
  private_constant :Foo

  def some_method
    ...
    catch(Foo){... another_method ...}
    ...
  end
  def another_method
    ...
    throw(Foo)
    ...
  end
end

关于ruby - 为什么有人会抛出非符号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35450221/

10-09 20:06
查看更多