2015-08-25 6 views

Répondre

8

Il semble vraiment que vous devriez être capable d'écrire,

trait X[T <: X[T]] 
object Y extends X[Y.type] 

cependant, si vous essayez que le compilateur vous donnera un peu serviable (et je pense faux) erreur,

scala> object Y extends X[Y.type] 
<console>:16: error: illegal cyclic reference involving object Y 
     object Y extends X[Y.type] 

Je dis "faux" parce que nous pouvons construire un objet équivalent avec un peu d'infrastructure supplémentaire,

Si vous vouliez expérimenter cela en code réel, l'utilisation d'un objet package à la place de object Fix rendrait cet idiome un peu plus utilisable.

+0

Pensez-vous que c'est un bug du compilateur ou est-ce un oubli dans la spécification? Ou peut-être y a-t-il une certaine subtilité que nous ne voyons pas qui rend l'erreur nécessaire? –

+3

Une conversation avec @retronym sur [scala/scala] (https://gitter.im/scala/scala?at=55dc7303fcfd5a7865af45d4) suggère que c'est un bug. Et il [fonctionne comme prévu sur Dotty] (https://gitter.im/lampepfl/dotty?at=55dc95a3a6bcd8894068e278). –

+0

https://github.com/scala/bug/issues/9844 –

1

Modifier à:

trait Y extends X[Y] 

object est pas un type à Scala, mais le soi-disant objet compagnon. En définissant object Y, vous ne pouvez pas exprimer qu'il doit s'étendre trait T[Y], puisque ce second Y fait référence à un type Y qui n'a pas été défini. Vous pouvez cependant effectuer les opérations suivantes:

trait Y extends X[Y]   //If you try this on the REPL, do :paste before 
object Y extends X[Y] 

Dans ce cas, l'objet Y étend X[Y] où le second Y est le trait que vous définissez juste, assurez-vous de garder cela à l'esprit.

+0

Je voudrais que Y ne soit instancié qu'une seule fois et accède à son instance unique, c'est pourquoi j'ai besoin d'un objet. –

+0

Ensuite, vous pouvez rendre le constructeur privé avec 'la classe Y private() étend X [Y]' et rend cette instance publiquement disponible. – Chirlo