集合的協方差

因為集合在元素型別*中通常是協變的,所以可以在期望超型別的地方傳遞子型別的集合:

trait Animal { def name: String } 
case class Dog(name: String) extends Animal

object Animal {
  def printAnimalNames(animals: Seq[Animal]) = {
    animals.foreach(animal => println(animal.name))
  }
}

val myDogs: Seq[Dog] = Seq(Dog("Curly"), Dog("Larry"), Dog("Moe"))

Animal.printAnimalNames(myDogs)
// Curly
// Larry
// Moe

它可能看起來不像魔術,但是 Seq[Dog] 被一個期望 Seq[Animal] 的方法接受的事實是一個更高階的型別(這裡:Seq)在其型別引數中是協變的整個概念。

*一個反例是標準庫的 Set