为什么Scala编译器说逆向类型A出现在类型>中的协变位置:A<:任何类型B?

时间:2013-02-03 23:19:15

标签: scala covariance contravariance

编译器告诉我这不能带有以下警告:“逆变类型A出现在类型>中的协变位置:A&lt ;:任何类型B”警告位于compose方法的type参数中。从逻辑上讲,类型定义对我来说很有意义。如果编译器没有使用andThen的问题,为什么会出现converse的问题?

trait Foo[-A]{
  def compose[B >: A](t: Foo[B]): Foo[A] = t andThen this
  def andThen[B <: A](t: Foo[B]): Foo[B]
}

我所需要的只是一个破坏的例子。然后我很高兴。

1 个答案:

答案 0 :(得分:4)

如错误所示,您的方差注释A是错误的。您不能在返回类型中使用A,这是一个协变位置。想象一下,你在Foo中有另一种方法,它在适当的逆变位置(作为参数)使用A

trait Foo[-A] {
  ...
  def foo(a: A): Unit
}

现在你可以看到这是如何崩溃的:

  • Foo[-A]表示Foo[X] <: Foo[Y]如果X >: Y
  • 返回的值可以是声明的返回类型的子类型
  • 因此,如果此处-A合法,compose可能会为某些Foo[A1]
  • 返回A1 >: A
  • trait Xtrait Y extends X { def bar() }
  • 想象Foo[Y]其中foo调用a.bar()
  • 因此,如果compose被允许返回Foo[X]
  • ,则会中断

因此,对于您编译的示例,A必须是不变的。