AnyRef 的奇怪模式匹配行为
def test1(a: Any) = a match {
case x: AnyRef => "AnyRef"
case _ => "None of the above"
}
def test2(a: Any) = a match {
case x: Double if x > 2 => "Double > 2"
case x: AnyRef => "AnyRef"
case _ => "None of the above"
}
请有人能解释为什么在下面,第一种情况 1.0
与 AnyRef
匹配,但在第二种情况下则不然。 (Scala 2.9.0-1)
scala> test1(1.0)
res28: java.lang.String = AnyRef
scala> test2(1.0)
res29: java.lang.String = None of the above
编辑 - Scala 2.10 更新于 2013 年 1 月:新的模式匹配器修复了此行为(或至少使其保持一致)和方法 test2
现在返回“AnyRef”,就像 test1
一样。
def test1(a: Any) = a match {
case x: AnyRef => "AnyRef"
case _ => "None of the above"
}
def test2(a: Any) = a match {
case x: Double if x > 2 => "Double > 2"
case x: AnyRef => "AnyRef"
case _ => "None of the above"
}
Please can someone explain why in the following, the first case 1.0
matches on AnyRef
, but in the second it doesn't. (Scala 2.9.0-1)
scala> test1(1.0)
res28: java.lang.String = AnyRef
scala> test2(1.0)
res29: java.lang.String = None of the above
edit - Scala 2.10 update Jan 2013: the new pattern matcher fixes this behaviour (or at least, makes it consistent) and the method test2
now returns "AnyRef" as for test1
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为
Any
实际上只是一个Object
。有了Double
,就有了一个方便的虚构——它实际上是java.lang.Double
,它在匹配语句中为您自动拆箱。不幸的是,Scala 无法判断它是否找到了java.lang.Double
,是否应该将其解释为Double
或java .lang.Double--在后一种情况下,
AnyRef
应该捕获它。确实如此。但是,如果您专门要求一个Double
,它知道它应该被拆箱,然后不需要检查AnyRef
情况。 (事实上,如果您希望它是 java.lang.Double,它也会将其拆箱——它无法区分差异。)这是否是理想的 /em> 行为是有争议的,但它是合乎逻辑的。
This is because
Any
is actually just anObject
. HavingDouble
there is a convenient fiction--it's actuallyjava.lang.Double
which is autounboxed for you in the match statement. Unfortunately, there is no way for Scala to tell if it finds ajava.lang.Double
if it is supposed to be interpreted as aDouble
or as ajava.lang.Double
--in the latter case, theAnyRef
should catch it. So it does. But if you specifically ask for aDouble
, it knows it is supposed to unbox, and then theAnyRef
case need not be checked. (And, in fact, if you intended it to be ajava.lang.Double
, it will unbox that too--it can't tell the difference.)Whether this is ideal behavior is debatable, but it is logical.