繁体   English   中英

类型参数中的Scala特征`this.type`

[英]Scala trait `this.type` in type parameter

看一下这两个简单的特征:

trait TreeNode1[S] {
    def subNodes: List[S]
}
trait TreeNode2 {
    def subNodes: List[this.type]
}

(并不是最好的命名方式,只是为了简短起见,将其重命名。)
TreeNode1定义一个具有其子级访问权限的树节点,指向其类型S
TreeNode2定义了相同的对象,但其子对象与混合当前特征的类具有相同的类型(换句话说,具有统一子节点的树节点)。

从理论上讲TreeNode2是一个特殊情况TreeNode1

trait TreeNode2 extends TreeNode1[this.type] {...}

但是Scala不会使用这种扩展来编译TreeNode2 ,因为不能以这种方式使用this.type ,尽管它在运行时的工作没有任何矛盾。

我如何解决这种情况? 还是Scala不提供这种使用不良的机制?


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

我还有另一个需要混合TreeNode1特性。我也有一些类将TreeNode1与另一TreeNode1类型混合在一起。 但是我也有几个类具有相同的类型:

class SomeTreeNode extends TreeNode1[SomeTreeNode]

因此,如果我使用TreeNode2 ,它将看起来更漂亮:

class SomeTreeNode extends TreeNode2

实现相同的逻辑。 但对于使用TreeNode2应的情况下TreeNode1 ,它实际上是,但斯卡拉不同意我的看法。

PS:至少,这是关于Scala的理论性问题,而不是广泛的实际使用。

它的子代与当前特质混杂的班级具有相同的类型

不。这是一个常见的误解。 this.type是的单类型this ; 只有两个值是thisnull 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模式),但是这对您是否有效取决于它们的使用方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM