使用带有收集的类型

时间:2011-09-05 13:19:06

标签: scala types type-erasure

我正在尝试根据类型动态过滤(或收集)列表:

如果我这样做明确指定类型,它可以正常工作

scala> var aList = List("one", 2, 3.3)
aList: List[Any] = List(one, 2, 3.3)

scala> aList.collect{case x:Int => x}
res10: List[Int] = List(2)

如果我想编写一个方法来执行此操作,那么它不会:

scala> def collectType[T](l:List[Any]):List[T] = l.collect{case x:T => x}
warning: there were unchecked warnings; re-run with -unchecked for details
collectType: [T](l: List[Any])List[T]

scala> collectType[Int](aList)
res11: List[Int] = List(one, 2, 3.3)

scala> collectType[Double](aList)  
res16: List[Double] = List(one, 2, 3.3)

scala> collectType[String](aList)
res14: List[String] = List(one, 2, 3.3)

我一开始认为它是在命名“Integer”类型而不是使用Integer作为类型,但似乎并非如此:

collectType[Int](aList).foreach(x => println(x))
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

就好像它会推迟检查类型,直到它被迫

我对类型缺少什么?

有没有办法实现我想要实现的目标?


阅读完链接的问题后,这就是我想出来的。现在很简单,已经指出了。 Taggable是一个知道如何保存类的标签映射的特性

def matches[F <: Taggable](thing:Taggable)(implicit m:Manifest[F]):Boolean = {
  thing match {
    case e if (m >:> singleType(e)) => true
    case x => false
  }
}
def findByType[G <: Taggable](list:List[Taggable])(implicit m:Manifest[G]) = {
  list.collect{case x if (matches[G](x)) => x}
}

1 个答案:

答案 0 :(得分:7)

您缺少type erasure。在运行时,您的方法实际上是

def collectType(l:List):List = l.collect {case x:Object => x}
相关问题