66 votes

Quelle est la différence entre A <: B et + B en Scala?

Quelle est la différence entre

 [A <: B]
 

et

 [+B]
 

à Scala?

168voto

Rex Kerr Points 94401

Q[A <: B] signifie que la classe Q peut prendre n'importe quelle classe A qui est une sous-classe de B.

Q[+B] signifie qu' Q peut prendre toute la classe, mais si A est une sous-classe de B, alors Q[A] est considéré comme une sous-classe de Q[B].

Q[+A <: B] signifie que la classe Q ne peuvent prendre que des sous-classes d' B ainsi que la multiplication de la sous-classe de la relation.

La première est utile lorsque vous voulez faire quelque chose de générique, mais vous avez besoin de s'appuyer sur un certain ensemble de méthodes en B. Par exemple, si vous avez un Output classe avec un toFile méthode, vous pouvez utiliser cette méthode dans une catégorie qui pourraient être adoptées en Q.

La seconde est utile lorsque vous souhaitez faire des collections qui se comportent de la même manière que les classes d'origine. Si vous prenez l' B et vous faire une sous-classe A, alors vous pouvez passer A - la partout où B est attendue. Mais si vous prenez une collection de B, Q[B], est-il vrai que vous pouvez toujours passer en Q[A] à la place? En général, non; il y a des cas où ce serait une mauvaise chose à faire. Mais vous pouvez dire que c'est la bonne chose à faire en utilisant +B (covariance; Q covaries-suit avec--B's sous-classes" relation d'héritage).

45voto

mucaho Points 95

Je voudrais étendre le Rex Kerr excellente réponse avec quelques exemples: Disons que nous avons quatre classes:

 class Animal {}
 class Dog extends Animal {}

 class Car {}
 class SportsCar extends Car {}

Commençons par la 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() )

Comme vous pouvez le voir Liste ne se soucie pas de savoir si elle contient des Animaux ou des Voitures. Les développeurs de Liste n'a pas d'appliquer, par exemple, les Voitures peuvent aller à l'intérieur des Listes.

En outre:

case class Shelter(animals: List[Animal]) {}

val animalShelter: Shelter = Shelter( List(new Animal()): List[Animal] )
val dogShelter: Shelter = Shelter( List(new Dog()): List[Dog] )

Si une fonction attend un List[Animal] paramètre, vous pouvez également passer une List[Dog] comme un argument de la fonction à la place. List[Dog] est considéré comme une sous-classe de List[Animal] en raison de la covariance de la Liste. Cela ne fonctionnera pas si la Liste est invariant.

Maintenant, sur le type de limites:

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())
                 ^
*/

Comme vous pouvez le voir Grange est une collection conçue uniquement pour les Animaux. Les voitures sont interdites ici.

2voto

Michele Points 3309

pour ma compréhension:


Le premier est un type de paramètre lié, il existe un type supérieur et inférieur dans notre cas, il s'agit d'un paramètre de type A qui est un sous-type de B (ou B lui-même).


La seconde est une annotation de variance pour une définition de classe, dans notre cas une sous-classe de covariance de B


Scala: + Java:? étend le sous-classement T Covariant

Scala: - Java:? super T sous-classement contravariant

2voto

Totoro Points 486

J'ai trouvé cet article de blog en recherchant cette question. Donne une explication encore plus profonde de la variance de Scala, y compris sa base théorique dans la théorie des catégories

http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X