【发布时间】:2013-11-29 18:25:22
【问题描述】:
我想我已经了解协方差和协方差的原理。但是似乎我在使用它时仍然遇到问题。 这是一个例子:我想编写一个简单的通用不可变容器,它具有一组固定的值。 所以我创建了一个基本的 Trait
trait Container[+A] {
type B <: A
def add(elem: B): Container[A]
}
然后我开始编写具体的类来表示具有不同数量值的不同容器,例如一个空容器和一个具有一个元素的容器
class Container0[+A] extends Container[A] {
def add(elem: B): Container[A] = new Container1[A](elem)
}
class Container1[+A](elem0: A) extends Container[A] {
def add(elem: B): Container[A] = new Container2[A](elem0, elem)
}
这编译得很好,但是当我尝试使用它时:
var t: Container[AnyVal] = new Container0[AnyVal]
t = t.add(5)
我收到以下错误:
type mismatch; found : Int(5) required: _3.B where val _3: Container[AnyVal]
【问题讨论】:
-
试试
trait Container[+A] { def add[B >: A](elem: B): Container[B] } -
_3.B类型是路径相关类型。当你在你的 trait 定义中说type B <: A时,你实际上是在说B可以在每个Container的实例中有所不同。编译器无法知道Int与t的当前值的特定类型B兼容。 -
使用 B >:A 没有解决问题:现在它的类型不匹配;找到:Container[_50.B] where val _50: Container[AnyVal] required: Container[AnyVal]
-
你正试图改变一个不可变的容器。
-
你能指出哪里吗? add 的返回类型是一个容器,所以我创建了一个全新的容器实例,它是前一个容器的副本 + 应该添加的元素。我认为这正是不可变的工作原理
标签: scala generics covariance