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.
This is because
Anyis actually just anObject. HavingDoublethere is a convenient fiction–it’s actuallyjava.lang.Doublewhich is autounboxed for you in the match statement. Unfortunately, there is no way for Scala to tell if it finds ajava.lang.Doubleif it is supposed to be interpreted as aDoubleor as ajava.lang.Double–in the latter case, theAnyRefshould catch it. So it does. But if you specifically ask for aDouble, it knows it is supposed to unbox, and then theAnyRefcase 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.