Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange pattern matching behaviour with 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"
}

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.

like image 784
Luigi Plinge Avatar asked Nov 10 '11 19:11

Luigi Plinge


1 Answers

This is because Any is actually just an Object. Having Double there is a convenient fiction--it's actually java.lang.Double which is autounboxed for you in the match statement. Unfortunately, there is no way for Scala to tell if it finds a java.lang.Double if it is supposed to be interpreted as a Double or as a java.lang.Double--in the latter case, the AnyRef should catch it. So it does. But if you specifically ask for a Double, it knows it is supposed to unbox, and then the AnyRef case need not be checked. (And, in fact, if you intended it to be a java.lang.Double, it will unbox that too--it can't tell the difference.)

Whether this is ideal behavior is debatable, but it is logical.

like image 123
Rex Kerr Avatar answered Nov 14 '22 23:11

Rex Kerr