2015-10-05 42 views
0

我實際上正在嘗試創建一個可以表示列中表格數據的類。這是我正在編寫的代碼的簡化模型,旨在說明令我困惑的關於scala類型的內容。如何定義可接受List [List [String]]和List [List [Int]]作爲輸入的案例類?

比方說,我有兩種類型

case class FunnyColumn[T](data:List[T]) 
case class FunnyTable(items:List[FunnyColumn[Any]]) 

我要開始添加的東西對我FunnyTable,所以這裏去。我做了一堆列,我可能要添加:

val intItem:FunnyColumn[Int] = new FunnyColumn(List(1,2,3)) 
val stringItem:FunnyColumn[String] = new FunnyColumn(List("A", "B", "C")) 
val untypedItem:FunnyColumn[Any] = new FunnyColumn(List(1,2,3)) 

到目前爲止好:

// works but seems icky, untyped FunnyColumns are not much use to me! 
val funny0 = new FunnyTable(List(untypedItem)) 

我真的不希望我的專欄是類型化的 - 我想我所有的列有意義的類型。在這個例子中,我已經試過(但失敗了)加FunnyColumn [字符串]:

// Fails because it wants List[FunnyColumn[Any]] but I gave it List[FunnyColumn[Int]] 
val funny1 = new FunnyTable(List(intItem)) 

這個問題似乎是因爲我定義爲FunnyTable接受字面上List[FunnyColumn[Any]],所以比Any列表以外的任何鍵入的FunnyColumns綁定失敗。

我想要做的就是就是讓這個我可以把任何FunnyColumn的變化到我FunnyTable,換句話說,這也應該工作:

// Fails because it wants List[FunnyColumn[Any]] but I gave it List[FunnyColumn[_ :> String with Int]] 
val funny2 = new FunnyTable(List(intItem, stringItem)) 

我如何重新定義我的FunnyTable類這樣我可以在其中存儲不同的FunnyColumn子類型?

回答

1

你需要讓FunnyColumn協在T

case class FunnyColumn[+T](data:List[T]) 

然後FunnyColumn[Any]FunnyColumn[Int]的超類型。

+0

這似乎是伎倆。有沒有一些參考資料可以解釋這個強大的魔法究竟是如何工作的? –

+0

@SalimFadhley - 你可能會發現這個[scala school](https://twitter.github.io/scala_school/type-basics.html#variance)頁有幫助。基本上,對於某些泛型類型的構造函數'F',即使A是B的超類型,F [A]也不會自動成爲F [B]的超類型。 'FunnyColumn'上的協方差註釋'+ T'使得你想要的列的關係。 – Lee

+0

「那麼FunnyColumn [Any]是FunnyColumn [Int]的子類型 - 當然你的意思是相反,FunnyColumn [Int]必須是FunnyColumn [Any]的子類型? –

相關問題