0

根据逆变的定义(将接受超类实例),我在下面的代码片段中的最后一条语句应该被接受;但它会抛出类型错误。请您纠正我的理解。

  class A
  class B extends A
  class C extends B
  
  abstract class Box[-T] {
     def set(x : T) :Unit
  }
  
  val x = new Box[B] {
    def set(b:B) = Console println "B"
  }
  
  val y  = new Box[A] {
    def set(a:A) = Console println "A"
  }
  
  val z  = new Box[C] {
    def set(c:C) = Console println "C"
  }  

  x.set(new A)   <-- Type error

不过 x.set(new C)还好!因此,即使“逆变参数被接受为方法参数”实际上也是协变参数。

4

2 回答 2

2

您对逆变的工作方式感到困惑。x是一个Box[B]本身,set接受类型的值B (或任何子类型,B因为这就是Liskvo所说的)

但是,Box[A]Box[B]子类型。所以你可以通过预期的地方。因为一个可以存储任何东西的Box可以存储一个. 但是,只能存储 s 的Box不能存储和任意。yxAB
BA

于 2020-11-13T17:32:09.250 回答
2

看起来这不是它的工作方式,这是从概念的角度来看:aB是一个A但不是相反的方式。

scala doc for variances所示,逆变类型参数允许传递“超类型”而不是“子类型”,但这适用于正文中使用的内容(例如,如果“超类型”已经已经定义了使用的内容)否则我猜它只考虑类型,我们回到我之前解释的内容。

于 2020-11-13T17:35:35.497 回答