2011-08-15 143 views
2

好吧,我現在開始獲得一些scala,但是每時每刻,更復雜的概念都讓我感到滿意。讓我介紹你到世界的水果:從泛型集合中選擇一個類型的子集

class Fruit 
class Pear extends Fruit 
class Apple extends Fruit 
class GrannySmith extends Apple 

現在,如果我想要一個新的泛型集合,讓我挑水果的子集了泛型集合的。天真的執行:

class MyArray[T](var a:Array[T]) { 
    def select[U <: T] = 
    a.filter(_ match { 
     case u:U => true 
     case _ => false 
    }) 
} 

但是這不起作用。

scala> var ma = new MyArray(
         Array(
          new Apple, 
          new Fruit, 
          new Pear, 
          new GrannySmith, 
          new Apple, 
          new Fruit 
         )) 


scala> ma.select[Apple] 
res1: Array[Fruit] = Array([email protected], [email protected], [email protected], [email protected], [email protected], [email protected]) 

控制檯警告未檢查的錯誤,與-unchecked重新運行給這個定義的同時MYARRAY:

<console>:8: warning: abstract type U in type pattern U is unchecked since it is eliminated by erasure 
      case u:U => true 

所以我喜歡的類型擦除的認識是很模糊的。我知道它與jvm中有限的動態類型有某種關係,並且有時你可以使用Manifests繞過它,因爲Daniel正在談論here。我特別不明白的是在這個例子中這是如何工作的,以及如何解決這個問題。

我很感謝任何幫助!

回答

3

這個怎麼樣?你甚至可以得到正確的返回類型。

ma.a.collect { case a: Apple => a } 
+0

......你可以說,我不小心公佈之前,我已經將我的實際問題=) – fickludd

+0

作品太好了 - 謝謝你啊!你的意思是ma.a.collect? – fickludd

+0

是的,更正,謝謝。 –