Différence entre les types existentiels de Scala et le caractère générique de Java par exemple?
-
06-07-2019 - |
Question
Un peu plus spécifique que la question de débordement de pile Qu'est-ce qu'un type existentiel? , quelle est la différence entre les types existentiels de Scala et le caractère générique de Java, de préférence avec un exemple illustratif?
Dans tout ce que j'ai vu jusqu'à présent, ils semblent être assez équivalents.
Quelques références. Martin Odersky les mentionne ; résultat de ma question :
>MO: Le modèle générique d'origine ... a été inspiré par des types existentiels. En fait, le document original avait un codage dans les types existentiels. Mais lorsque la conception finale est sortie en Java, cette connexion s’est un peu perdue
La solution
Voici la réponse de Martin Odersky sur la liste de diffusion de Scala-users:
Les types de caractères génériques Java originaux (décrits dans le document ECOOP de Igarashi et Viroli) étaient en effet juste des raccourcis pour existentielle les types. On me dit et j'ai lu dans l'article de FOOL '05 sur Wild FJ que la version finale de joker a quelques différences subtiles avec types existentiels. Je ne saurais pas exactement dans quel sens (leur le formalisme est trop éloigné des types existentiels classiques pour être capable de repérer la différence), mais peut-être une lecture attentive du Wild Le papier de FJ ferait la lumière dessus.
Il semble donc que les types existentiels Scala et les caractères génériques Java sont des types équivalents
Autres conseils
Ils sont supposés être équivalents, leur objectif principal étant d'interagir avec les caractères génériques de Java.
Ils sont très similaires mais le type existentiel de Scala est supposé être plus puissant. Par exemple, le type existentiel de Scala peut être à la fois supérieur et inférieur, alors que le caractère générique de Java ne peut être que superposé.
Par exemple, dans Scala:
scala> def foo(x : List[_ >: Int]) = x
foo: (x: List[_ >: Int])List[Any]
le foo prend une liste de paramètre qui a une limite inférieure de Int.
Une réponse plus détaillée de Martin Odersky (le reste peut être trouvé ici ):
Scala a besoin de types existentiels pour essentiellement trois choses. La première est-ce que nous devons donner un sens aux caractères génériques de Java, et types existentiels est le sens que nous en donnons. La seconde est que nous besoin de donner un sens aux types bruts de Java, car ils sont également toujours dans les bibliothèques, les types non générés. Si vous obtenez un Java brut type, tel que java.util.List, c’est une liste où vous ne connaissez pas la type d'élément. Cela peut aussi être représenté en Scala par un existentiel type. Enfin, nous avons besoin de types existentiels pour expliquer ce qui se passe dans la VM au niveau élevé de Scala. Scala utilise le modèle d'effacement des génériques, tout comme Java, donc nous ne voyons pas les paramètres de type plus lorsque les programmes sont exécutés. Nous devons effacer parce que nous avons besoin d'interopérer avec Java. Mais alors qu'est-ce qui se passe quand on fait de la réflexion ou voulez exprimer ce qui se passe dans la VM? Nous devons pouvoir représente ce que la machine virtuelle Java utilise en utilisant les types que nous avons dans Scala, et types existentiels nous le faisons. Ils vous ont laissé parler de types où vous ne connaissez pas certains aspects de ces types.
La notation List [_]
(qui, comme le soulignent d’autres réponses, est un analogue plus puissant que celui de List [?]
de Java) est un cas dégénéré de la notion plus générale d'un type existentiel dans Scala.