2010-06-03 51 views
3

類型的方法,我很新的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)後它們具有相同的參數類型。

想法歡迎!

回答

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並允許它被稱爲多態。

+0

感謝您的詳細解釋! – stephanos 2010-06-04 10:39:24

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])) 
    } 
+1

感謝您的建議 - 但實際上問題在其他地方。你看,我有_multiple_ convert方法(參見上面的UPDATED描述) - 當我爲列表編寫一個通用的轉換方法時,Scala找不到合適的轉換方法。 – stephanos 2010-06-03 15:42:05

+2

恐怕,你必須做一個明確的模式匹配:( 隱式類型轉換不會幫助解決這個問題。 – 2010-06-03 19:14:26