Выбор подмножества типов из общей коллекции - PullRequest
2 голосов
/ 15 августа 2011

Ладно, ребята, я сейчас начинаю получать скалы, но время от времени меня ловят хитрые концепции.Позвольте мне познакомить вас с фруктовым миром:

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(Apple@4d815146, Fruit@64fef26a, Pear@1ddd40f3, GrannySmith@28d320d6, Apple@3d10d68a, Fruit@1c751d58)

Консоль предупреждала о непроверенных ошибках, повторный запуск с -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, и что иногда вы можете обойти это, используя Манифесты, когда Даниил говорит о здесь .Что я особенно не понимаю, так это то, как это работает в этом примере, и как можно обойти это.

Я благодарен за любую помощь!

1 Ответ

3 голосов
/ 15 августа 2011

Как насчет этого? Вы даже получаете правильный тип возврата.

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