2010-09-03 32 views
6

Estoy jugando con scala (scala 2.8). Supongamos que tengo una clase con un rasgo anidado, y quiero usar ese rasgo anidado como el tipo para un parámetro en el constructor de la clase. ¿Es eso posible? Esto es lo más cerca que he llegado:Rasgo anidado en el constructor de clase en scala

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

Sin la tercera línea que incluso compila, pero tan pronto como trato de utilizar realmente el traitParam como InnerTrait consigo un error del compilador:

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

No puedo entender qué (si hay algo) podría hacer. Haciendo

class OuterClass(traitParam:OuterClass.this.InnerTrait) 

en su lugar, como el mensaje de error podría sugerir, no se compila. ¿Tengo otra opción que no sea mover InnerTrait fuera de OuterClass? Si se pregunta por qué me gustaría hacer esto, la respuesta es que en mi código real, el equivalente a OuterClass tiene parámetros de tipo que luego se usarían en InnerTrait. Si lo muevo hacia afuera, entonces tengo que replantear los parámetros de tipo cada vez que hago referencia al rasgo interno.

Respuesta

7

Te encuentras con Scala tipos dependientes de ruta. el tipo de su val y: InnerTrait es específico de la instancia en la que está contenido. OuterClass#InnerTrait es un supertipo de todas las InnerTrait existentes para todas las instancias de OuterClass.

trate de trabajar con esto:

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

Por lo tanto, es posible tener a: OuterClass y b: OuterClass de tal manera que estos parámetros de tipo son diferentes. Por ejemplo:

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

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

Así que aquí es el dilema ... InnerTrait debe estar ligada a una instancia de OuterClass, ya que cada instancia podría tener un parámetro de tipo diferente. Sin embargo, desea pasar un InnerTrait como parámetro al constructor OuterClass, por lo que deberá construir InnerTrait antes de OuterClass. Pero dado que InnerTrait tiene que estar vinculado a una instancia de OuterClass, entonces OuterClass debe construirse antes de InnerClass, convirtiéndolo en un problema de huevo de pollo &.

Hay algo extraño en ese diseño, por lo que le sugiero que lo vuelva a intentar.

Cuestiones relacionadas