【发布时间】:2015-03-10 22:04:54
【问题描述】:
class X[A](val value: A){
def unapply[B <: A](x: X[B]) = true
}
object Main extends App {
val int = new X(1)
val string = new X("a")
val pf: PartialFunction[Any, Int] = { case o @ int() => o.value }
println(pf(string) + 1)
}
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
我认为这段代码应该抛出一个 scalac 应该警告此代码。MatchError 而不是ClassCastException。或
Scala 2.11.5
已编辑:
Scala 2.9.3 警告如下。但不是 2.10、2.11
Main.scala:8: warning: non variable type-argument B in type pattern X[B] is unchecked since it is eliminated by erasure
val pf: PartialFunction[Any, Int] = { case o @ int() => o.value }
^
我从一开始就理解类型擦除。
换句话说,pf.isDefinedAt(string) 返回 true 但 pf.apply(string) 抛出 ClassCastException
Welcome to Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_67).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
class X[A](val value: A){
def unapply[B <: A](x: X[B]) = true
}
val int = new X(1)
val string = new X("a")
val pf: PartialFunction[Any, Int] = { case o @ int() => o.value }
// Exiting paste mode, now interpreting.
defined class X
int: X[Int] = X@4f3cb3fc
string: X[String] = X@1a4c8e08
pf: PartialFunction[Any,Int] = <function1>
scala> pf.isDefinedAt(string)
res0: Boolean = true
scala> pf.apply(string)
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
... 33 elided
【问题讨论】:
-
看起来像类型擦除问题,Scala无法区分
X[Int]和X[String],所以匹配是正数,但是函数返回类型是Int而值是String。跨度>
标签: scala pattern-matching classcastexception partialfunction