Nested trait in class constructor in scala
I'm playing around with scala (scala 2.8). Suppose I have a class with a nested trait, and want to use that nested trait as the type for a parameter in the class's constructor. Is that even possible? This is the closest I've come:
class OuterClass(traitParam:OuterClass#InnerTrait) {
trait InnerTrait { }
val y:InnerTrait = traitParam
}
Without the third line that even compiles, but as soon as I try to actually use the traitParam
as an InnerTrait
I get a compiler error:
type mismatch; found: OuterClass#InnerTrait required: OuterClass.this.InnerTrait.
I can't figure out what (if anything) I could do. Doing
class OuterClass(traitParam:OuterClass.this.InnerTrait)
instead, as the error message might suggest, does not compile. Do I have any choice other than to move InnerTrait
outside of OuterClass
? If you're wondering why I would want to do this, the answer is that in my 开发者_高级运维actual code, the equivalent of OuterClass
has type parameters which would then be used in InnerTrait
. If I move it outside, then I have to restate the type parameters every time I reference the inner trait.
You're encountering Scala's path-dependent types. your val y: InnerTrait
's type is specific to the instance in which it's contained. OuterClass#InnerTrait
is a supertype of all the InnerTrait
extant for all instances of OuterClass
.
Try working with this:
class OuterClass(traitParam: OuterClass#InnerTrait) {
trait InnerTrait { }
type IT = OuterClass#InnerTrait
def m1: IT = traitParam
}
OuterClass has type parameters which would then be used in InnerTrait
So it is possible to have a: OuterClass
and b: OuterClass
such that these type parameters are different. For instance:
abstract class OuterClass[T] {
val x: T
}
val a = new OuterClass[Int] { val x = 5 }
val b = new OuterClass[String] { val x = "abc" }
So here is the conundrum... InnerTrait
must be tied to an instance of OuterClass
, since each instance might have a different type parameter. However, you want to pass an InnerTrait
as parameter to OuterClass
constructor, so you'll need to construct InnerTrait
before OuterClass
. But since InnerTrait
has to be tied to an instance of OuterClass
, then OuterClass
must be constructed before InnerClass
, turning this into a chicken & egg problem.
There's something strange with that design, so I suggest you rethink it through.
精彩评论