Je suis nouveau dans l'utilisation de Scala et j'ai rencontré le problème suivant :
Je veux obtenir une sous-collection d'une collection existante qui ne contient que des éléments d'un type spécifique. La méthode suivante fonctionne :
class C(val name : String)
class D(name : String) extends C(name) { }
val collection = Set[C](new C("C1"),new D("D1"),new C("C2"),new D("D2"))
collection.collect{case d : D => d}.size must be === 2 // works
Mais lorsque j'essaie d'étendre les classes de collection avec une méthode "onlyInstancesOf[Type]", cela ne fonctionne pas. D'abord mon implémentation :
object Collection {
implicit def extendScalaCollection[E](coll : Traversable[E]) = new CollectionExtension[E](coll)
}
class CollectionExtension[E](coll : Traversable[E]) {
def onlyInstancesOf[SpecialE <: E] : Traversable[SpecialE] = {
coll.collect({case special : SpecialE => special}).asInstanceOf[Traversable[SpecialE]]
}
}
Donc quand j'utilise cette extension et que j'exécute :
collection.onlyInstancesOf[D].size must be === 2
Je reçois un message d'erreur indiquant que .size a renvoyé 4 et non 2. De plus, j'ai vérifié, le résultat contient effectivement C1 et C2 alors qu'il ne devrait pas.
Quand je le fais :
collection.onlyInstancesOf[D].foreach(e => println(e.name))
Je comprends l'exception :
java.lang.ClassCastException: CollectionsSpec$$anonfun$1$C$1 cannot be cast to CollectionsSpec$$anonfun$1$D$1
Il est donc évident que l'ensemble résultant contient toujours les éléments qui auraient dû être filtrés.
Je ne comprends pas pourquoi cela se produit, quelqu'un peut-il l'expliquer ?
Edit : Scala : Scala code runner version 2.8.0.final