2012-12-16 84 views
0

的類型,下面我有:列表按照參數

trait Elem { 
    def compare: Int 
} 

case class DiffElem(weight: Int, len: Int) extends Elem { 
    def compare = weight - len; 
} 

現在可以有ELEM的很多子類的基礎上,compare功能。 現在我有一個功能,即從文件讀取輸入並生成DiffElem列表:

def getInput[T <: Elem](): List[T] = { 
    var ans: List[T] = List.empty[T] 
    for (line <- Source.fromFile("src/week1/jobs.txt").getLines()) { 
    val diff = line.split(" ") 
    ans = ans match{ 
     case i:List[DiffElem] => new DiffElem(Integer.parseInt(diff(0)), Integer.parseInt(diff(1))) :: ans; 
     case _ => ??? 
    } 

    } 
    ans 
} 

但是編譯器不允許的操作,顯然爲::如下禁忌變異型,我試圖做的不變性。如果我的函數簽名轉換爲T >: Elem那麼它的工作原理,但目的不就解決了。

任何更好的辦法?

回答

3

如果你正在構建DiffElem內getInput,那麼如何(爲什麼)你想獲得任意牛逼<的列表:ELEM?要做到這樣的事情,你應該能夠從DiffElem轉換爲任何其他牛逼<:ELEM,那可兌換可以用隱含捕獲這樣的:

def getInput[T <: Elem](implicit conv: DiffElem => T): List[T] = ... 

,但你真的想要嗎?如果你會發現DiffElem的只是列表,你可以這樣重寫你的函數功能性風格:

def getInput(): List[DiffElem] = 
    Source.fromFile("src/week1/jobs.txt").getLines().map { line => 
     val diff = line.split(" ") 
     DiffElem(
     Integer.parseInt(diff(0)), 
     Integer.parseInt(diff(1)) 
    ) 
    } toList 

map是高階函數捕獲序列的每個元素的轉化應用的結果它的funarg這個元素。

更新: 爲了使模塊式驅動的列表創建我會建議implicits:

def getInput[E <: Elem](implicit mkE: (Int, Int) => E): List[E] = { 
    Source.fromFile("src/week1/jobs.txt").getLines().map { line => 
     val diff = line.split(" ")  
     mkE(diff(0).toInt, diff(1).toInt)  
    } toList 
    } 

現在,任E <:ELEM,你想要得到的名單,你應該提供類型的隱式值(INT,INT)=>電子進入範圍,如:

implicit val diffElemBuilder = { 
    (a, b) => DiffElem(a, b) 
    } 

而且在任何範圍內,其中,這種隱含是可見的,可以使用getInput這樣的:

val xs = getInput[DiffElem] 
+0

有了這個,它會創建DiffElem列表。如果存在着擴展ELEM另一個類,我想創建一個列表?我嘗試通過模式匹配來完成ti,基於通用類型,我可以生成列表 – Jatin

+0

Hm,是否需要某種類型驅動的列表創建:使用帶顯式類型參數的getInput來獲取不同類型的列表(像getInput [DiffElem]()來獲得DiffElem的和getInput [AnotherElem()來獲得AnotherElems列表)名單? – aemxdp

+0

是的,正是如此。 – Jatin

-1

您可能會重構代碼並使用排名較高的多態函數而不是模式匹配。