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)
我认为此代码应抛出 ascalac 应该警告此代码。MatchError
而不是ClassCastException
. 或者
斯卡拉 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