協方差
+符號將型別引數標記為協變 - 這裡我們說“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
}