在集合上应用重载的类型化方法

时间:2010-06-03 10:38:14

标签: scala

我对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 个答案:

答案 0 :(得分:4)

不要认为您需要该方法的通用参数。 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 :(得分:1)

你需要做类型转换:

  //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]))
  }