2010-09-03 91 views
6

我正在玩斯卡拉(斯卡拉2.8)。假设我有一个具有嵌套特征的类,并且想要将该嵌套特征用作类的构造函数中参数的类型。这甚至有可能吗?这是我来最接近:斯卡拉在类构造函数中的嵌套特质

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

没有,即使编译第三行,但只要我尝试实际使用traitParam作为InnerTrait我得到一个编译错误:

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

我无法弄清楚我可以做什么(如果有的话)。做

class OuterClass(traitParam:OuterClass.this.InnerTrait) 

而是,如错误消息可能表明,不会编译。除了在OuterClass以外移动InnerTrait之外,还有其他选择吗?如果您想知道为什么我想要这样做,答案是在我的实际代码中,OuterClass的等效参数的类型参数会在InnerTrait中使用。如果我将它移到外面,那么每次参考内在特质时都必须重新说明类型参数。

回答

7

您遇到了Scala的路径依赖类型。您的val y: InnerTrait的类型特定于其包含的实例。 OuterClass#InnerTrait是存在于OuterClass的所有实例中的所有InnerTrait的超类型。

尝试这方面的工作:

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

所以可能有a: OuterClassb: OuterClass使得这些类型的参数是不同的。例如:

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

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

因此,这里的难题... InnerTrait必须连接到的OuterClass一个实例,因为每个实例可能有不同的类型参数。但是,您想要将InnerTrait作为参数传递给OuterClass构造函数,因此您需要在OuterClass之前构造InnerTrait。但由于InnerTrait必须绑定到OuterClass的实例,因此必须在InnerClass之前构建OuterClass,将其转化为鸡蛋问题。

这个设计有些奇怪,所以我建议你重新考虑一下。