gpt4 book ai didi

ruby - 为什么有人会抛出一个非符号?

转载 作者:数据小太阳 更新时间:2023-10-29 08:30:55 25 4
gpt4 key购买 nike

Ruby 的 throw 语句接受任何 Object,这意味着下面的任何对象都是合法的。

throw BasicObject
throw 123456.78
throw "wow"
throw :doge

然而,据我所知,我选择抛出一个 Symbol 有两个原因。

  1. 必须 catch 与抛出的完全相同的 Object。这意味着执行 catch "wow" 会导致 UncaughtThrowError。这在使用 Symbol 时不是问题。
  2. catch 之后无法引用抛出的 Object。要指定返回值,可以将其作为第二个参数输入:throw :doge, "wow" 在我看来,这会破坏抛出自定义 Object ..

此外,令人困惑的是,在 ruby 1.9 之前,throw 的(第一个)参数曾经被限制为 Symbols。这是否意味着有人必须 throw 非符号,而 ruby​​ 必须更改其实现以允许此类用例?或者是其他原因......比如节省类型检查的执行时间。

在这一点上,我唯一能想到的与 Symbol 分开的是 Fixnum,但这是改变的原因吗?请赐教。

最佳答案

假设您正在使用一些您不关心其内部结构的库。如果该库使用带有特定符号(或任何其他常见对象)的 throw 方法,而该符号恰好与您正在 throw 的符号(或对象)相同,该怎么办-在你自己的代码中?它会导致不必要的交互。另一方面,如果你创建一个自定义对象并抛出它,你就不必关心这样的问题。特别是如果您只将它定义为局部变量,那将是安全的。如果你把它定义为一个常量,那么它会相对安全(危险是其他库不小心在同一个 namespace 中使用相同的常量名称)。

catch 带有一个 block 参数创建一个 Object 的实例,并将其分配为一个 block 变量,这使其安全。

当我使用 throw 时,我通常不能使用 block 变量形式,因为大多数时候,我在不同的地方使用 throwcatch方法。因此,我创建了一个 Object 的实例,并将其分配为私有(private)常量,这使其相对安全。

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com