大小写相等运算符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
是出于性能原因吗?
答案 0 :(得分:1)
你弄错了。 Array#===
是定义的(更准确地说,Array#===
本身没有定义,但它继承了)。如果没有定义,则代码会引发错误。
当a
为Array
时,a === obj
在true
时定义为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运算符可用于覆盖离散集用例。
由于范围不是嵌套结构,因此这些类型的问题根本不适用。