ruby的throw
语句接受任何Object
,这意味着下面的任何一个都是合法的。
throw BasicObject
throw 123456.78
throw "wow"
throw :doge
然而,据我所知,我选择抛出
Symbol
有两个原因。一个人必须
catch
与抛出的Object
完全相同。这意味着执行catch "wow"
将导致UncaughtThrowError
。使用Symbol
s时这不是问题。在
Object
之后不能引用抛出的catch
。要指定返回值,可以将其作为第二个参数输入:throw :doge, "wow"
这将破坏在我看来抛出自定义Object
的整个要点。此外,令人困惑的是
throw
的(第一个)参数以前被限制在Symbols
之前。这难道不意味着有人必须ruby 1.9
非符号,而ruby必须改变他们的实现以允许这样的用例吗?或者是别的什么…比如为类型检查节省执行时间。在这一点上,我能想象的除了
throw
s之外的唯一东西是Symbol
s,但这是改变的原因吗?请启发我。 最佳答案
假设您正在使用某个库,而您并不关心它的内部。如果该库使用带有某个符号(或任何其他公共对象)的throw
方法,而该符号(或对象)碰巧与您在自己的代码中使用的throw
符号(或对象)相同,该怎么办?它会导致不必要的互动。另一方面,如果您创建一个自定义对象并抛出它,则不必关心此类问题。特别是如果您只将其定义为局部变量,它将是安全的。如果将其定义为常量,则相对安全(危险在于另一个库在相同的名称空间中意外使用了相同的常量名称)。
带有块参数的catch
创建Object
的实例,并将其作为块变量分配,这样就安全了。
当我使用throw
时,我通常不能使用块变量形式,因为大多数情况下,我使用不同的方法throw
和catch
。因此,我创建了一个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/