定义协变和逆变类型时出错

Vla*_*mir 5 scala

我有代码:

class A {
    override def toString = "object class A"
}

class B extends A {
    override def toString = "object class B"
}

class Cell[+T](init: T) {
    private[this] var current: T = init
    def get: T = current
    def set(x: T) { current = x }
}

val cB = new Cell[B](new B)
println(cB.get)
val cA: Cell[A] = cB
println(cA.get)
Run Code Online (Sandbox Code Playgroud)

但我有错误: def set(x: T) { current = x }

错误:协变类型T出现在类型T中的逆变位置x def set(x:T){current = x}

请解释

Kim*_*bel 5

类型的逆变位置(以及其他)允许您将该类型的实例传递给方法的任何位置.因此所有方法参数类型都处于逆变位置.由于您将T声明为covariant(+T),因此编译器不允许这样做.您唯一的选择是:

  • 使T不变
  • 修改设定方法,使得它返回的一个新实例CellCell因此成为一成不变的.
  • 删除set方法,也使Cell不可变

如果编译器允许您在实现它时使用set方法,那将使类型系统不安全,因为它允许您编写:

val cs:Cell[String] = new Cell("")
val ca:Cell[Any] = cs
ca.set(5)
val s:String = cs.get //boom
Run Code Online (Sandbox Code Playgroud)