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