Question

Dans la variance Scala peut être définie avec les opérateurs de la variance comme + et - sur l'argument de type générique. Par exemple, le type de List est covariante dans la bibliothèque standard.

class List[+A]

une fonction avec une liste covariant peut être définie comme ceci:

def foo[A](list : List[A])

variance aussi peut être émulé avec des limites génériques. Donc, on peut aussi écrire ce

def foo[A](list : List[_:< A])

Bien sûr, cela n'a pas de sens, parce que list est déjà covariant. Mais la même astuce pourrait être fait pour les types qui ne sont pas covariant. (Comme Stack). Bien sûr, aussi un nouveau type pourraient être créés à partir de la pile (héritage d'agrégation) qui est covariante.

Alors mes questions:

  1. Quand faut-il utiliser des limites génériques pour la variance? Et quand devrions-nous créer un nouveau type covariant?
  2. sont limites génériques utiles que la variance, ou peuvent-ils déclarer plus (concepts linguistiques).
  3. Si elles ne sont utiles que pour la variance, sont limites alors que pour la compatibilité avec Java?

thx à l'avance:)

Était-ce utile?

La solution

Si un type est naturellement vous covariant ou contravariant déclarerait ainsi. Vos utilisateurs vous en remercie. La variance utilisation du site est en effet la plupart du temps là-bas à cause de Java. Plus précisément, un type tel que Array[T <: Number] est traité comme un raccourci pour un type existentiel:

ArrayBuffer[T] forSome { type T <: Number }

types existentiels ont une syntaxe assez volumineuse à Scala. C'est un peu intentionnel, parce que nous ne vous recommandons pas les utiliser beaucoup. Quand souhaitez-vous besoin d'un type existentiel?

  1. Pour écrire l'analogue d'un type Java avec des caractères génériques, tels que List<? extends Number>.
  2. Pour écrire l'analogue d'un type brut Java, tels que List.

En Java, les types et les types génériques bruts ne sont pas tout à fait la même ni est tout à fait le même que celui d'un type existentiel (même si nous savons ce qu'ils ne sont pas, il est assez difficile d'indiquer avec précision ce qu'ils sont). Mais ils sont assez proches de la pratique existentiaux, de sorte que Scala se avec eux à cartographier ce genre de type.

Autres conseils

  1. Lors de la création d'un nouveau type générique, par exemple Foo [T], vous devriez essayer difficile de déterminer si ce type est covariant, contravariante ou invariant et déclarer Foo [+ T], Foo [-T] ou Foo [T] respectivement. Il est vrai que cela peut être un peu difficile. Cependant, il libère l'utilisateur de Foo de prendre cette décision à chaque fois qu'elle a besoin d'utiliser un Foo en utilisant des limites génériques. En bref: préférez la variance du site de déclaration sur la variance du site d'appel lorsque la variance est une propriété du type lui-même.

BTW, la programmation dans le livre Scala par Martin Odersky, Lex Spoon et Bill Venners a quelques grands seactions sur la variance. Voir le chapitre 19 Type paramétrisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top