2017-09-08 3 views
3

Existe-t-il une raison pour la restriction qu'une classe de valeur ne peut pas envelopper une autre classe de valeur?Pourquoi une classe de valeur ne peut-elle pas envelopper une autre classe de valeur?

Il semble évident de vouloir le faire et d'étendre les avantages à la hiérarchie des classes. Si class B(val x: A) extends AnyVal peut être traité comme compile-time-only, et utilise la classe A dans les coulisses, alors ce serait bien si class C(val y: B) extends AnyVal pouvait faire la même chose. Il est implémenté de manière transparente sous la forme B, qui est implémentée de manière transparente sous la forme A lors de l'exécution dans la machine virtuelle Java, de sorte que tous les avantages de l'efficacité et de la surcharge gc sont reportés sur la classe C.

Pourquoi la restriction?

+0

Je devine, que c'est possible de faire, mais exige un peu d'effort du côté du compilateur néanmoins. Et avoir une telle capacité n'est pas vraiment très utile, alors, ils ont décidé de le couper. Vous pouvez toujours faire 'la classe C (val y: A) étend AnyVal', et ensuite, quand vous avez besoin de quelque chose de' B' à l'intérieur de 'C', faites juste' B (y) .doStuff' qui est seulement un peu plus long que 'y.doStuff', et n'est pas plus sage performance sage. – Dima

+0

* Pourquoi la restriction? * Pour voir cela comme une restriction, cela signifie que vous avez conclu que cette fonctionnalité vaut la peine d'être ajoutée à la langue mais qu'elle est limitée en raison d'une limitation technique. Je voudrais demander, pourquoi auriez-vous besoin de le faire en premier lieu? Du point de vue du langage, 'B' est quasiment toujours invisible (à moins d'être utilisé dans un cas particulier, pourquoi ne pas l'utiliser), pourquoi voudriez-vous en créer un wrapper? Quel est l'avantage d'utiliser directement 'A'? –

Répondre

2

Il s'agit d'une restriction d'implémentation. Il est levé dans Dotty:

$ dotr 
Starting dotty REPL... 
scala> case class C1(i: Int) extends AnyVal 
// defined case class C1 
scala> case class C2(c1: C1) extends AnyVal 
// defined case class C2 
scala> val x = C2(C1(1)) 
val x: C2 = C2(C1(1))