2013-02-03 35 views
6

编译器告诉我这不能带来以下警告:“逆变类型A发生在类型>中的协变位置:A <:任何类型B.”警告在撰写方法的类型参数中。从逻辑上讲,类型定义对我来说很有意义。如果编译器没有问题,那么,为什么问题与之相反?为什么Scala编译器会说在类型为>:A <:类型B的任何类型的协变位置出现逆变类型A?

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

所有我需要的是一个例子,它分解了。然后我很高兴。

回答

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必须是不变的。

相关问题