协方差
+符号将类型参数标记为协变 - 这里我们说“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
}