What's the difference between A<:B and +B in Scala?

后端 未结 4 1455
挽巷
挽巷 2021-01-29 18:20

What\'s the difference between

[A <: B]

and

[+B]

in Scala?

4条回答
  •  时光说笑
    2021-01-29 18:50

    I would like to extend Rex Kerr's excellent answer with some more examples: Let's say we have four classes:

     class Animal {}
     class Dog extends Animal {}
    
     class Car {}
     class SportsCar extends Car {}
    

    Let's start with variance:

     case class List[+B](elements: B*) {} // simplification; covariance like in original List
    
     val animals: List[Animal] = List( new Dog(), new Animal() )
     val cars: List[Car] = List ( new Car(), new SportsCar() )
    

    As you can see List does not care whether it contains Animals or Cars. The developers of List did not enforce that e.g. only Cars can go inside Lists.

    Additionally:

    case class Shelter(animals: List[Animal]) {}
    
    val animalShelter: Shelter = Shelter( List(new Animal()): List[Animal] )
    val dogShelter: Shelter = Shelter( List(new Dog()): List[Dog] )
    

    If a function expects a List[Animal] parameter you can also pass a List[Dog] as an argument to the function instead. List[Dog] is considered a subclass of List[Animal] due to the covariance of List. It would not work if List was invariant.

    Now onto type bounds:

    case class Barn[A <: Animal](animals: A*) {}
    
    val animalBarn: Barn[Animal] = Barn( new Dog(), new Animal() )
    val carBarn = Barn( new SportsCar() )
    /* 
    error: inferred type arguments [SportsCar] do not conform to method apply's type parameter bounds [A <: Animal]
        val carBarn = Barn(new SportsCar())
                     ^
    */
    

    As you can see Barn is a collection only intended for Animals. No cars allowed in here.

提交回复
热议问题