Je finis généralement par essayer toutes les combinaisons jusqu'à ce qu'elles soient compilées. Quelqu'un peut-il expliquer ce que je devrais utiliser où?
Réponses
Trop de publicités?Je ne serai pas d'accord avec Chris réponse à un égard. Les classes Any
, AnyRef
et AnyVal
sont des classes. Mais ils n'apparaissent pas comme des classes en bytecode, en raison de limitations intrinsèques de la JVM.
Cela découle du fait que tout n'est pas en Java est un objet. En plus des objets, il y a des primitives. Tous les objets Java sont des descendants de java.lang.Object
, mais les primitives sont mis à part et, actuellement, l'*, non extensible par un programmeur. Notez également que les primitives ont des "opérateurs", et non pas des méthodes.
En Scala, de l'autre côté, tout est un objet, tous les objets appartenant à une classe, et ils interagir par le biais de méthodes. La JVM du bytecode généré ne pas en tenir compte, mais qui ne les rend pas moins, tout comme en Java génériques, même si le bytecode n'y en a pas.
Donc, en Scala, tous les objets sont des descendants de Any
, et qui comprend à la fois ce que Java considère les objets et ce que Java considère primitives. Il n'y a pas d'équivalent en Java, car il n'y a pas une telle unification.
Tout ce qui est considéré comme un primitifs en Java est descendant d' AnyVal
en Scala. Jusqu'à la Scala 2.10.0, AnyVal
a été scellé, et les programmeurs étaient pas en mesure de le prolonger. Il devrait être intéressant de voir ce qui va se passer avec Scala .Net, étant donné que l'interopérabilité seuls les appels pour Scala à au moins reconnaître défini par l'utilisateur "primitives".
Aussi étendre Any
est AnyRef
, ce qui est équivalent à java.lang.Object
(sur la JVM en tout cas).
Jusqu'à la Scala 2.9.x, un utilisateur ne peut pas s'étendre Any
ou AnyVal
, ni de référence de Java, mais il y ont été à d'autres usages qu'ils pourraient être mis à la Scala. Plus précisément, type de signatures:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
Ce que chaque moyen devrait être évident à partir de la hiérarchie de classe. Il convient de noter, toutefois, est qu' f
et h
automatique-boîte, mais g
ne le seront pas. C'est un peu le contraire de ce que Java n', qui f
et h
ne peut pas être spécifié, et g
(défini avec java.lang.Object
) serait la cause de l'auto-boxing.
En commençant par Scala 2.10.0, cependant, l'utilisateur peut étendre AnyVal
ou Any
, avec la sémantique suivante:
Si une classe étend
AnyVal
, aucune instance sera créée sur le tas, sous certaines conditions. Cela signifie que les champs de cette classe (sur 2.10.0 un seul champ est autorisée, si cela va changer reste à voir) va rester sur la pile, qu'elles soient primitives ou des références à d'autres objets. Cela permet à des méthodes d'extension sans l'instanciation des coûts.Si un trait s'étend
Any
, alors il peut être utilisé avec les deux classes qui étendentAnyRef
et les classes qui étendentAnyVal
.
PS: Dans mon propre point de vue, Java est susceptible de suivre C# en permettant "struct" primitives, et peut-être typedefs, que le parallélisme sans avoir recours à eux, s'avère difficile à réaliser avec de bonnes performances.
Vu ca? Le texte de la page contient quelques remarques sur l’interopérabilité java. http://www.scala-lang.org/node/128
Any
et AnyVal
font, je crois, partie du système de types scala et ne sont pas des classes en tant que telles (de la même manière que Nothing
est un type, pas une classe). Vous ne pouvez pas les utiliser explicitement à partir de code Java.
Cependant, dans l'interopérabilité Java / Scala, une méthode qui accepte un Java Object
s'attend à un scala Any
- AnyRef
.
Que tentez-vous réellement de faire?