协方差

+符号将类型参数标记为协变 - 这里我们说“ProducerA 上是协变的”:

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
}

处理此限制的一种方法是使用由协变类型参数限定的类型参数。在下面的例子中,我们知道 BA 的超类型。因此,对于 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
}