Использование типа с коллекцией - PullRequest
3 голосов
/ 05 сентября 2011

Я пытаюсь динамически фильтровать (или собирать) список по типу:

Если я делаю это явно, указав тип, он отлично работает

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 Ответ

7 голосов
/ 05 сентября 2011

Вам не хватает типа стирания .Во время выполнения ваш метод на самом деле

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