为什么在范围#===时没有定义数组#===?

时间:2014-09-26 12:43:45

标签: ruby

大小写相等运算符Range#===存在并使用Range #include?内心如果我没有弄错的话。

# prints "foo"
case 2
when (1..3)
  puts "foo"
end

我想知道为什么这不是Array类的情况......在我看来,它打破了最不令人意外的原则。我希望这可行,但事实并非如此。

# does not print "foo"
case 2
when [1, 2, 3]
  puts "foo"
end

是出于性能原因吗?

3 个答案:

答案 0 :(得分:1)

你弄错了。 Array#=== 定义的(更准确地说,Array#===本身没有定义,但它继承了)。如果没有定义,则代码会引发错误。

aArray时,a === objtrue时定义为a == obj,而您的代码不会打印"foo",因为[1, 2, 3]不是2

答案 1 :(得分:1)

之所以如此,是因为===由案例陈述在内部使用。

在给定case (4..10)时,

5匹配是有意义的; case [4, 5, 6, 7, 8, 9, 10]更少。 (如果需要匹配case语句中数组的任何元素,可以将其展开:case *[4, 5, 6, 7, 8, 9, 10]

答案 2 :(得分:0)

我完全同意Array稍微破坏了字符,因为没有提供“如果a是一个集合,那么=== b是b是否是其他核心类提供的语义的一部分”。也就是说,Ruby中===的主要目的是允许类支持case ... when statement。

我猜这个区别来自于案例......当涉及数组的语句将被处理时:

case [1, 2]
when [1, 2]
when [1, 2, 3]
when [1, 2, [1, 2]]
end

你可以看到所有场景都可以匹配的论证,每个场景都有不同的原因。

我认为最终太模糊了。如前所述,splat运算符可用于覆盖离散集用例。

由于范围不是嵌套结构,因此这些类型的问题根本不适用。