看到这个实现苹果和桔子遵循上限例如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