类型参数中的Scala trait`this.type`

类型参数中的Scala trait`this.type`,scala,inheritance,traits,Scala,Inheritance,Traits,看看这两个简单的特征: trait TreeNode1[S] { def subNodes: List[S] } trait TreeNode2 { def subNodes: List[this.type] } (不是最好的命名,只是为了简短而重命名了它们。) TreeNode1定义一个树节点及其子节点访问,指向其类型S TreeNode2定义了相同的属性,但其子节点的类型与当前特征混合的类相同(换句话说,具有统一子节点的树节点) 理论上,树节点2是树节点1的特例: trai

看看这两个简单的特征:

trait TreeNode1[S] {
    def subNodes: List[S]
}
trait TreeNode2 {
    def subNodes: List[this.type]
}
(不是最好的命名,只是为了简短而重命名了它们。)
TreeNode1
定义一个树节点及其子节点访问,指向其类型
S

TreeNode2
定义了相同的属性,但其子节点的类型与当前特征混合的类相同(换句话说,具有统一子节点的树节点)

理论上,树节点2是树节点1的特例:

trait TreeNode2 extends TreeNode1[this.type] {...}
但是Scala不会使用这样的扩展编译
TreeNode2
,因为
这个.type
不能以这种方式使用,尽管它在运行时的工作没有任何不一致之处

我怎样才能摆脱这种局面?还是Scala没有提供如此糟糕的使用机制


我需要这种结构的原因如下:

我还有另一个特点,需要将
TreeNode1
混合在一起。我还有一个类将
TreeNode1
与另一个完全不同的子类型混合在一起。但我也有几个类的类型与它们相同:

class SomeTreeNode extends TreeNode1[SomeTreeNode]
因此,如果我使用
TreeNode2
,它看起来会更漂亮:

class SomeTreeNode extends TreeNode2
实现相同的逻辑。但是使用
TreeNode2
应该是
TreeNode1
的一个例子,实际上是这样,但是Scala不同意我的观点

另外,至少它是作为一个关于Scala的理论问题,而不是为了广泛的实际应用

它的孩子与班级类型相同,但目前的特点是混合的

不,这是一个常见的误解
this.type
this
的单例类型;即。
TreeNode2
实例的所有子实例必须是同一个实例

要回答问题的另一部分,一个选项是使
S
成为类型成员而不是类型参数:

trait TreeNode1 {
    type S
    def subNodes: List[S]
}
object TreeNode1 {
    // use TreeNode1.Aux[S] where you had TreeNode1[S] originally
    type Aux[T] = TreeNode1 { type S = T }
}

trait TreeNode2 {
    type S = this.type // not really what you want
    def subNodes: List[this.type]
}
(所谓的
Aux
模式),但这是否适用于您取决于它们的使用方式