isInstanceOf與型別擦除
阿新 • • 發佈:2019-02-01
轉載自:http://hongjiang.info/scala-pitfalls-11-type-erasure/
scala中用isInstanceOf判斷一個物件例項是否是某種型別時,如果型別包含引數型別,會被擦除(jvm的做法)。所以會導致例如下面的問題:
scala中用isInstanceOf判斷一個物件例項是否是某種型別時,如果型別包含引數型別,會被擦除(jvm的做法)。所以會導致例如下面的問題:
在給出了一段警告之後,結果返回true,如果資料物件支援模式匹配且元素較少,可以用模式匹配來精確判斷:scala> (1,2).isInstanceOf[Tuple2[String,String]] <console>:14: warning: fruitless type test: a value of type (Int, Int) cannot also be a (String, String) (but still might match its erasure) (1,2).isInstanceOf[Tuple2[String,String]] ^ res11: Boolean = true
scala> (1,2) match{ case(_:Int, _:Int) => println("ok"); case _ => "no"}
ok
res12: Any = ()
但元素比較多的話,或資料不支援模式匹配,要判斷引數型別,就需要讓編譯器在執行時保持引數型別的資訊了,在scala裡是通過TypeTag來實現的,TypeTag知識點參考http://hongjiang.info/scala-type-system-manifest-vs-typetag/。如下方式可以作型別檢查:scala> def checkType[A: TypeTag](a: A, t: Type) = typeOf[A] <:< t checkType: [A](a: A, t: reflect.runtime.universe.Type)(implicit evidence$1: reflect.runtime.universe.TypeTag[A])Boolean scala> checkType((1,2), typeOf[Tuple2[String,String]]) res13: Boolean = false scala> checkType((1,2), typeOf[Tuple2[Int,Int]]) res14: Boolean = true