Странное поведение сопоставления шаблонов с 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

edit - Scala 2.10 update Jan 2013: новый шаблонный шаблон исправляет это поведение (или, по крайней мере, делает его согласованным), а метод test2 теперь возвращает "AnyRef", как для test1.

Ответ 1

Это потому, что Any на самом деле просто Object. Имея Double, есть удобная фикция - она ​​фактически java.lang.Double, которая автоматически выдается вам в матче. К сожалению, для Scala нет способа определить, найдет ли он java.lang.Double, если он предполагается интерпретировать как Double или как java.lang.Double - в последнем случае AnyRef должен поймать Это. Так оно и есть. Но если вы специально спросите Double, он знает, что он должен распаковываться, а затем не нужно проверять случай AnyRef. (И, на самом деле, если вы намеревались быть java.lang.Double, он тоже будет отключен), это не может отличить.)

Является ли это идеальное поведение дискуссионным, но это логично.