协方差
+
符号将类型参数标记为协变 - 这里我们说“Producer
在 A
上是协变的”:
trait Producer[+A] {
def produce: A
}
协变类型参数可以被认为是输出类型。将 A
标记为协变断言 Producer[X] <: Producer[Y]
提供了 X <: Y
。例如,Producer[Cat]
是有效的 Producer[Animal]
,因为所有产生的猫也是有效的动物。
协变类型参数不能出现在逆变(输入)位置。以下示例将不会编译,因为我们断言 Co[Cat] <: Co[Animal]
,但是 Co[Cat]
有 def handle(a: Cat): Unit
,它无法处理 Co[Animal]
所要求的任何 Animal
!
trait Co[+A] {
def produce: A
def handle(a: A): Unit
}
处理此限制的一种方法是使用由协变类型参数限定的类型参数。在下面的例子中,我们知道 B
是 A
的超类型。因此,对于 X <: Y
,我们知道 Option[X]
的 def getOrElse[B >: X](b: => B): B
可以接受 X
的任何超类型 - 其中包括 Option[Y]
所要求的 Y
的超类型:
trait Option[+A] {
def getOrElse[B >: A](b: => B): B
}