2010-09-03 7 views
6

Je joue avec scala (scala 2.8). Supposons que j'ai une classe avec un trait imbriqué et que je veuille utiliser ce trait imbriqué comme type pour un paramètre dans le constructeur de la classe. Est-ce que c'est possible? Ceci est le plus proche que je suis venu:Caractère imbriqué dans le constructeur de la classe dans scala

class OuterClass(traitParam:OuterClass#InnerTrait) { 
    trait InnerTrait { } 
    val y:InnerTrait = traitParam 
} 

Sans la troisième ligne qui compile même, mais dès que je tente d'utiliser réellement le traitParam comme InnerTrait je reçois une erreur de compilation:

type mismatch; found: OuterClass#InnerTrait required: OuterClass.this.InnerTrait.

Je ne peux pas comprendre ce que (si quelque chose) je pourrais faire.

class OuterClass(traitParam:OuterClass.this.InnerTrait) 

à la place, comme le message d'erreur peut suggérer, ne compile pas. Ai-je d'autre choix que de déplacer InnerTrait en dehors de OuterClass? Si vous vous demandez pourquoi je voudrais faire cela, la réponse est que dans mon code actuel, l'équivalent de OuterClass a des paramètres de type qui seraient ensuite utilisés dans InnerTrait. Si je le déplace à l'extérieur, je dois reformuler les paramètres de type chaque fois que je fais référence au caractère interne.

Répondre

7

Vous rencontrez les types dépendants du chemin de Scala. le type de votre val y: InnerTrait est spécifique à l'instance dans laquelle il est contenu. OuterClass#InnerTrait est un supertype de tous les InnerTrait existants pour toutes les instances de OuterClass.

Essayez de travailler avec ceci:

class OuterClass(traitParam: OuterClass#InnerTrait) { 
    trait InnerTrait { } 

    type IT = OuterClass#InnerTrait 

    def m1: IT = traitParam 
} 
1

OuterClass has type parameters which would then be used in InnerTrait

Il est donc possible d'avoir a: OuterClass et b: OuterClass de telle sorte que ces paramètres de type sont différents. Par exemple:

abstract class OuterClass[T] { 
    val x: T 
} 

val a = new OuterClass[Int] { val x = 5 } 
val b = new OuterClass[String] { val x = "abc" } 

Voici donc l'énigme ... InnerTrait doit être liée à une instance de OuterClass, puisque chaque instance peut avoir un paramètre de type différent. Cependant, vous voulez passer un InnerTrait comme paramètre au constructeur OuterClass, donc vous devrez construire InnerTrait avant OuterClass. Mais puisque InnerTrait doit être lié à une instance de OuterClass, alors OuterClass doit être construit avant InnerClass, ce qui en fait un problème de poulets &.

Il y a quelque chose d'étrange dans ce design, alors je vous suggère de le repenser.

Questions connexes