Я новичок в Scala и столкнулся со следующей проблемой:
Я хочу получить вложенную коллекцию существующей коллекции, которая содержит только элементы определенного типа. Следующие работы:
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
Но когда я пытаюсь расширить классы коллекции с помощью метода "onlyInstancesOf [Type]", это не работает. Первая моя реализация:
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]]
}
}
Поэтому, когда я использую это расширение и выполняю:
collection.onlyInstancesOf[D].size must be === 2
Я получаю ошибку, что .size вернул 4, а не 2. Кроме того, я проверил, что результат на самом деле содержит C1 и C2, хотя не должен.
Когда я делаю:
collection.onlyInstancesOf[D].foreach(e => println(e.name))
Я получаю исключение:
java.lang.ClassCastException: CollectionsSpec$$anonfun$1$C$1 cannot be cast to CollectionsSpec$$anonfun$1$D$1
Таким образом, очевидно, что результирующий набор все еще содержит элементы, которые должны были быть отфильтрованы.
Я не понимаю, почему это происходит, кто-нибудь может объяснить это?
Edit:
Scala: бегун с кодом Scala версии 2.8.0.final