Depuis Scala 2.7.2, il y a quelque chose appelé Manifest
qui est une solution de contournement pour l'effacement de type de Java. Mais comment Manifest
fonctionne exactement et pourquoi / quand devez-vous l'utiliser?
Le billet de blog Manifests: Reified Types de Jorge Ortiz en explique une partie, mais n'explique pas comment l'utiliser avec les limites de contexte .
De plus, quelle est ClassManifest
la différence avec Manifest
?
J'ai du code (qui fait partie d'un programme plus large, je ne peux pas facilement l'inclure ici) qui contient quelques avertissements concernant l'effacement de type; Je suppose que je peux résoudre ces problèmes en utilisant des manifestes, mais je ne sais pas exactement comment.
Réponses:
Le compilateur connaît plus d'informations sur les types que le runtime JVM ne peut facilement en représenter. Un manifeste est un moyen pour le compilateur d'envoyer un message interdimensionnel au code au moment de l'exécution sur les informations de type qui ont été perdues.
Ceci est similaire à la façon dont les Kleptoniens ont laissé des messages codés dans les archives fossiles et l'ADN «indésirable» des humains. En raison des limites de la vitesse de la lumière et des champs de résonance gravitationnelle, ils sont incapables de communiquer directement. Mais, si vous savez comment syntoniser leur signal, vous pouvez bénéficier d'une manière que vous ne pouvez pas imaginer, en décidant quoi manger pour le déjeuner ou quel numéro de loto jouer.
Il n'est pas clair si un manifeste bénéficierait des erreurs que vous voyez sans connaître plus de détails.
Une utilisation courante des Manifests consiste à faire en sorte que votre code se comporte différemment en fonction du type statique d'une collection. Par exemple, que se passe-t-il si vous souhaitez traiter une List [String] différemment des autres types de List:
Une solution basée sur la réflexion impliquerait probablement d'inspecter chaque élément de la liste.
Un contexte lié semble le plus adapté à l'utilisation de classes de types dans scala, et est bien expliqué ici par Debasish Ghosh: http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html
Les limites de contexte peuvent également rendre les signatures de méthode plus lisibles. Par exemple, la fonction ci-dessus pourrait être réécrite en utilisant des limites de contexte comme ceci:
la source
Pas une réponse complète, mais en ce qui concerne la différence entre
Manifest
etClassManifest
, vous pouvez trouver un exemple dans la Scala 2.8Array
papier :Exemple:
(Voir cette question SO pour illustration )
la source
Un manifeste était destiné à réifier les types génériques qui sont effacés de type pour s'exécuter sur la JVM (qui ne prend pas en charge les génériques). Cependant, ils avaient de sérieux problèmes: ils étaient trop simplistes et étaient incapables de prendre en charge pleinement le système de types de Scala. Ils ont donc été déconseillés dans Scala 2.10, et sont remplacés par
TypeTag
s (qui sont essentiellement ce que le compilateur Scala lui-même utilise pour représenter les types, et donc supporte pleinement les types Scala). Pour plus de détails sur la différence, consultez:En d'autres termes
Avant le 04/01/2013, date de sortie de Scala 2.10 .
la source
Voyons aussi
manifest
dansscala
sources (Manifest.scala
), nous voyons:Donc, en ce qui concerne l'exemple de code suivant:
nous pouvons voir que la
manifest
function
recherche d'un implicitem: Manifest[T]
qui satisfait le quetype parameter
vous fournissez dans notre exemple de code c'étaitmanifest[String]
. Donc, lorsque vous appelez quelque chose comme:vous vérifiez si le courant
implicit m
que vous avez défini dans votre fonction est de typemanifest[String]
et commemanifest
est une fonction de type,manifest[T]
il chercherait un spécifiquemanifest[String]
et il trouverait s'il existe un tel implicite.la source