我已经检查它是否是下面的函数List[Int]或List[String].但如果我检查如下,总是如此.为什么以及如何定义要检查List[Int]或List[String]键入的函数.
if(checkIntCollection(List("q","aa","aa"))){
Logger.info("it is true")
} else {
Logger.info("it is false")
}
Run Code Online (Sandbox Code Playgroud)
要么
if(checkIntCollection(List(1,2,3))){
Logger.info("it is true")
} else {
Logger.info("it is false")
}
Run Code Online (Sandbox Code Playgroud)
以下是检查: -
def checkIntCollection[T](v: T) : Boolean = v match {
case _: List[Int] =>
Logger.info("It is List[Int] found")
true
case _ =>
Logger.info("It is unknown")
false
}
def checkStringCollection[T](v: T) : Boolean = v match {
case _: List[String] =>
Logger.info("It is List[String] found")
true
case _ =>
Logger.info("It is unknown")
false
}
Run Code Online (Sandbox Code Playgroud)
正如在其他答案中所提到的,类型擦除使得匹配表达式检查List而不是List[Int],因此结果不像人们预期的那样.
但是,您可以使用TypeTags来规避多态类型的类型擦除.需要注意的是TypeTagS ^ 可能使用Reflection可能产生负面影响性能.
import scala.reflect.ClassTag
import scala.reflect.runtime.universe._
object RichClass {
def unapply[T](a: RichClass[T]): Option[T] = Option(a.value)
}
implicit class RichClass[T](val value: T)(implicit val classTag: ClassTag[T], val typeTag: TypeTag[T]) {}
def isType[T : ClassTag : TypeTag](richClass: RichClass[_]): Boolean = {
richClass match {
case RichClass(elem: T) if richClass.typeTag.tpe =:= typeOf[T] => true
case _ => false
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它
val stringList = List("A", "B")
val intList = List(1, 2, 3)
assert(isType[List[String]](stringList))
assert(!isType[List[String]](intList))
assert(isType[List[Int]](intList))
assert(!isType[List[Int]](stringList))
Run Code Online (Sandbox Code Playgroud)
由于类型擦除,这种情况正在发生.如果您使用警告进行编译,您会注意到它表示您的类型测试没用,因为包含的类型在运行时不可见.
在运行时,类型T是List,而不是List[String]或List[Int]
事实上,你试图做到这一点就会产生很大的代码味 - 你怎么不知道你拥有什么?