看到這個實現蘋果和桔子遵循上限例如http://docs.scala-lang.org/tutorials/tour/upper-type-bounds.html斯卡拉協文檔例如允許
class Fruit(name: String)
class Apple (name: String) extends Fruit(name)
class Orange(name: String) extends Fruit(name)
class BigOrange(name:String) extends Orange(name)
class BigFLOrange(name:String) extends BigOrange(name)
// Straight from the doc
trait Node[+B ] {
def prepend[U >: B ](elem: U)
}
case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
def prepend[U >:B ](elem: U) = ListNode[U](elem, this)
def head: B = h
def tail = t
}
case class Nil[+B ]() extends Node[B] {
def prepend[U >: B ](elem: U) = ListNode[U](elem, this)
}
但這個定義似乎允許多個不相關的東西,在同一容器
val f = new Fruit("fruit")
val a = new Apple("apple")
val o = new Orange("orange")
val bo = new BigOrange("big orange")
val foo :ListNode[BigOrange] = ListNode[BigOrange](bo, Nil())
foo.prepend(a) // add an apple to BigOrangeList
foo.prepend(o) // add an orange to BigOrangeList
val foo2 : ListNode[Orange] = foo // and still get to assign to OrangeList
所以我不確定這是否是文檔中的一個很好的例子。而且,問題是,我如何修改約束條件以便...這個行爲更像是一個List?
User @gábor-bakos指出我混淆了不變性與協變性。所以我嘗試了可變列表緩衝區。它並不後來讓蘋果被插入到橙色清單緩衝器,但它不是協變
val ll : ListBuffer[BigOrange]= ListBuffer(bo)
ll += bo //good
ll += a // not allowed
So..can我上面的例子(ListNode)已被修改,以便 1.它是協變(它是) 二是可變的,但可變像ListBuffer例子(以後不會允許蘋果被插入BigOrange列表
我不確定你的意思/問。你想要一個協變列表的行爲像一個不變列表嗎? –
嗯,好的。所以協方差和不變性是2個不同的概念。我怎樣才能讓這個例子不變?具體來說,我該如何添加一個推斷類型的構造函數,即編譯器會將以下內容標記爲無效: – user7938511
以使其不變,並在B之前移除「+」號。另外,在'prepend'中放寬類型參數,並使參數類型爲'B'。 – Dima