为什么会抛出一个非符号?

coz*_*tel 2 ruby

Ruby的throw声明接受任何Object,这意味着以下任何一个都是合法的.

throw BasicObject
throw 123456.78
throw "wow"
throw :doge
Run Code Online (Sandbox Code Playgroud)

然而,根据我的理解,我选择抛出一个原因有两个原因Symbol.

  1. 一个必须catch完全相同的Object抛出.这意味着做catch "wow"会导致一个UncaughtThrowError.使用Symbols 时这不是问题.
  2. Object那个被扔不能以后引用catch.要指定返回值,可以将其作为第二个参数输入:throw :doge, "wow"这会破坏Object我认为抛出自定义的整点.

此外,令人困惑的是,(第一个)论证throw过去曾被限制在此Symbols之前ruby 1.9.难道这不意味着有人必须使用throw非符号,并且ruby必须更改其实现以允许此类用例吗?或者它是别的......就像节省类型检查的执行时间一样.

在这一点上,我唯一可以想象Symbol的是Fixnum,与s 分开的是s,但这是改变的原因吗?请赐教.

saw*_*awa 5

假设您正在使用一些您不关心其内部的库.如果该库使用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
Run Code Online (Sandbox Code Playgroud)