scala中用isInstanceOf
判断一个对象实例是否是某种类型时,如果类型包含参数类型,会被擦拭掉(jvm的做法)。所以会导致例如下面的问题:
scala> (1,2).isInstanceOf[Tuple2[String,String]]
<console>:11: 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]]
^
res33: Boolean = true
在给出了一段警告之后,结果返回true
,如果数据对象支持模式匹配且元素较少,可以用模式匹配来精确判断:
scala> (1,2) match{ case(_:Int, _:Int) => println("ok"); case _ => "no"}
ok
但元素比较多的话,或数据不支持模式匹配,要判断参数类型,就需要让编译器在运行时保持参数类型的信息了,在scala里是通过TypeTag
来实现的,参考scala类型系统:19) Manifest与TypeTag
scala> def checkType[A: TypeTag](a: A, t: Type) = typeOf[A] <:< t
scala> checkType((1,2), typeOf[Tuple2[String,String]])
res37: Boolean = false
scala> checkType((1,2), typeOf[Tuple2[Int,Int]])
res38: Boolean = true
最近在拜读您的博客,这里有个问题请教下,def checkType[A: TypeTag](a: A, t: Type) = typeOf[A] <:< t 这个函数我在交互界面上可以定义并调用,但是在IDEA中定义时却报 Error:(29, 49) not found: value typeOf。。。这错误,我在代码中已经import scala.reflect._。不知道为何,请指教,多谢!
typeOf是runtime包对象里的universe实例里的方法,要这样引入:import scala.reflect.runtime.universe._
解决了,我用的gradle构建项目,添加了 ‘scala’插件,但是IDEA好像没把scala-reflect引进来,显式地添加该依赖就可以了。多谢!
scala> def tt(msg:(Any,Any))=msg match{case (_:Int,_:Int)=>println(“ok”);c
>”wrong”}
tt: (msg: (Any, Any))Any
scala> tt((1,2))
ok
res123: Any = ()
scala> tt((1,”b”))
res124: Any = wrong
def tt(msg:(Any,Any))=msg match{case (_:Int,_:Int)=>println(“ok”);case _=>”wrong”}
少复制了点,看您这里的内容:https://hongjiang.info/scala-pitfalls-13/