2011-09-05 80 views
3

我試圖動態過濾器(或收集)的列表基於類型類型:使用與收集

如果我這樣做明確指定類型,它工作正常

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) 

我開始還以爲它被命名類型「整型」,而不是使用整數作爲類型,但是這似乎並沒有情況如下:

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

就好像它的推遲,直到它被迫

我缺少的是關於類型檢查的類型?

有沒有辦法實現我想達到的目的?


通過閱讀鏈接的問題後,這就是我想出的。現在已經指出它很簡單。加標籤是它知道如何把握地圖上標記爲一類

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} 
} 
+0

'警告:有未經檢查的警告;用-unchecked查看詳細信息,然後重新運行 – soc

回答

7

你缺少type erasure一個特點。在運行時,您的方法實際上是

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

謝謝,是的,我終於發現了一個類似於我的問題(我在尋找真實信息之前曾經搜索過很多信息,但沒有找到正確的單詞組合)http:// stackoverflow。 com/questions/3660217/scala-collection-filter-by-type – CPJ

+0

Alexey的答案中的鏈接還表明,您可以通過將類型重新定義爲運行時「Manifest」對象來解決類型刪除問題。 –

+0

@CPJ:最好把它添加到你的問題的最後。評論中的多行代碼相當難以理解。 –