Scala Type Parameters 2

  • 類型關係scala

    Scala 支持在泛型類上使用型變註釋,用來表示複雜類型、組合類型的子類型關係間的相關性code

    • 協變 +T,變化方向相同,一般用在生產it

      假設 A extends T, 對於 Clazz[+T],則 Clazz[A] 也可看作 Clazz[T]class

      // 官網示例
      abstract class Animal {
        def name: String
      }
      case class Cat(name: String) extends Animal
      case class Dog(name: String) extends Animal

      因爲 Scala 標準庫中不可變 List 的定義爲 List[+A],所以 List[Cat]List[Animal] 的子類型, List[Dog] 也是 List[Animal] 的子類型,因此可直接將他們看成 List[Animal] 使用。泛型

      // 官網示例
      object CovarianceTest extends App {
        def printAnimalNames(animals: List[Animal]): Unit = {
          animals.foreach { animal =>
            println(animal.name)
          }
        }
      
        val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
        val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))
      
        printAnimalNames(cats)
        // Whiskers
        // Tom
      
        printAnimalNames(dogs)
        // Fido
        // Rex
      }
    • 逆變 -T,變化方向相反,一般用在消費object

      假設 A extends T, 對於 Clazz[-T],則 Clazz[T] 也可看作 Clazz[A]foreach

      // 官網示例
      abstract class Printer[-A] {
        def print(value: A): Unit
      }
      
      class AnimalPrinter extends Printer[Animal] {
        def print(animal: Animal): Unit =
          println("The animal's name is: " + animal.name)
      }
      
      class CatPrinter extends Printer[Cat] {
        def print(cat: Cat): Unit =
          println("The cat's name is: " + cat.name)
      }
      
      object ContravarianceTest extends App {
        val myCat: Cat = Cat("Boots")
      
        def printMyCat(printer: Printer[Cat]): Unit = {
          printer.print(myCat)
        }
      
        val catPrinter: Printer[Cat] = new CatPrinter
        val animalPrinter: Printer[Animal] = new AnimalPrinter
      
        printMyCat(catPrinter)
        printMyCat(animalPrinter) // 將 Printer[Animal] 看成 Printer[Cat] 使用
      }
相關文章
相關標籤/搜索