Странное поведение сопоставления с шаблоном с AnyRef - PullRequest
11 голосов
/ 10 ноября 2011
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 Янв 2013 : новый сопоставитель шаблонов исправляет это поведение (или, по крайней мере, делает его непротиворечивым), а метод test2 теперь возвращает «AnyRef», как для test1.

1 Ответ

6 голосов
/ 11 ноября 2011

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

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

...