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'。 –