大小写等于运算符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
是出于性能原因吗?
你理解错了。定义了Array#===
(更准确地说,Array#===
本身没有定义,但它继承了)。如果没有定义,那么您的代码会引发错误。
当a
是Array
时,a === obj
在true
被定义为a == obj
,而你的代码不打印"foo"
,因为[1, 2, 3]
不是2
。
就像那样,因为===
在案例陈述中被内部使用。
给予case (4..10)
有意义的5
匹配; case [4, 5, 6, 7, 8, 9, 10]
少了。 (如果你需要在case语句中匹配数组的任何元素,你可以splat它:case *[4, 5, 6, 7, 8, 9, 10]
。
我完全同意Array有点破坏字符,因为没有提供“如果a是一个集合,那么=== b是b是否是其他核心类提供的语义的一部分。也就是说,Ruby中===的主要目的是允许类支持case ... when语句。
我想差异来自于案例...当涉及数组的语句将被处理时:
case [1, 2]
when [1, 2]
when [1, 2, 3]
when [1, 2, [1, 2]]
end
您可以看到所有方案都匹配的可能性,每个方案都有不同的原因。
我觉得最后太模糊了。如前所述,splat运算符可用于覆盖离散集用例。
由于范围不是嵌套结构,因此这些类型的问题根本不适用。