与AnyRef的奇怪模式匹配行为

时间:2011-11-10 19:43:23

标签: scala pattern-matching

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.0AnyRef匹配,但在第二个案例中却没有。 (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”,如同{ {1}}。

1 个答案:

答案 0 :(得分:6)

这是因为Any实际上只是ObjectDouble有一个方便的小说 - 它实际上是java.lang.Double,它在match语句中为你自动装箱。不幸的是,如果Scala应该被解释为java.lang.DoubleDouble,那么Scala无法判断它是否找到java.lang.Double - 在后一种情况下,{ {1}}应该抓住它。它确实如此。但是,如果你专门询问 AnyRef,它知道它应该取消装箱,然后不需要检查Double的情况。 (事实上​​,如果你打算将它作为AnyRef,那么它也会拆开它 - 它无法区分它。)

这是否是理想的行为是值得商榷的,但这是合乎逻辑的。