Применение перегруженных типизированных методов к коллекции - PullRequest
3 голосов
/ 03 июня 2010

Я довольно новичок в Scala и борюсь со следующим:

У меня есть объекты базы данных (тип BaseDoc) и объекты значений (тип BaseVO). Теперь есть несколько методов преобразования (все они называются «преобразовать»), которые берут экземпляр объекта и соответственно преобразуют его в другой тип - например:

def convert(doc: ClickDoc): ClickVO = ...
def convert(doc: PointDoc): PointVO = ...
def convert(doc: WindowDoc): WindowVO = ...

Теперь мне иногда нужно преобразовать список объектов. Как бы я это сделал - я попробовал:

def convert[D <: BaseDoc, V <: BaseVO](docs: List[D]):List[V] = docs match {
    case List() => List()
    case xs => xs.map(doc => convert(doc))
}

В результате 'перегруженное значение метода конвертируется с альтернативами ...'. Я пытался добавить к нему информацию о манифесте, но не смог заставить его работать.

Я даже не мог создать один метод для каждого, потому что он сказал бы, что они имеют один и тот же тип параметра после стирания типа (List).

Идеи приветствуются!

Ответы [ 2 ]

4 голосов
/ 04 июня 2010

Не думайте, что вам нужны общие параметры метода. List уже ковариантен в Scala. Вам также не нужно совпадение с шаблоном - map преобразует пустой список в себя. Как насчет этого:

def convert(docs: List[BaseDoc]):List[BaseVO] = docs map {
    case doc: ClickDoc => convert(doc)
    case doc: PointDoc => convert(doc)
    case doc: WindowDoc => convert(doc)
}

Другой вариант - переместить методы convert в различные подклассы BaseDoc и разрешить его полиморфный вызов.

1 голос
/ 03 июня 2010

Вам нужно сделать приведение типа:

  //case class MyBaseDoc(x: Int, y: Int)
  //case class BaseVO(x: Int, y: Int)
  //case class ClickDoc(x: Int, y: Int) extends MyBaseDoc(x, y)
  //case class ClickVO(var x: Int, var y: Int) extends BaseVO(x, y)

  def convert(doc: ClickDoc): ClickVO  = doc match {
    case null => null
    case _ =>
      val result = new ClickVO
      result.x = doc.x
      result.y = doc.y
      result
  }


  def convert(docs: List[MyBaseDoc]):List[BaseVO] = docs match {
    case List() => List()
    case xs => xs.map(doc => convert(doc.asInstanceOf[ClickDoc]))
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...