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应该警告这段代码。这是scalac bug吗?MatchError
代替ClassCastException
。或者
斯卡拉2.11.5
编辑:
斯卡拉2.9.3警告如下。但不是2.10
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] = [email protected]
string: X[String] = [email protected]
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
貌似类型擦除问题,斯卡拉不能X [INT]'和'X [字符串]''之间的区别,所以比赛是积极的,但函数返回类型是'Int',而值是'String'。 –