[英]Scala trait `this.type` in type parameter
Have a look at these two simple traits: 看一下这两个简单的特征:
trait TreeNode1[S] {
def subNodes: List[S]
}
trait TreeNode2 {
def subNodes: List[this.type]
}
(Not best naming, renamed them just to be brief.) (并不是最好的命名方式,只是为了简短起见,将其重命名。)
TreeNode1
defines a tree node with its children access, pointing their type S
. TreeNode1
定义一个具有其子级访问权限的树节点,指向其类型S
TreeNode2
defines the same, but its children have the same type as the class the current trait is mixed in (another words, tree node with uniform subnodes). TreeNode2
定义了相同的对象,但其子对象与混合当前特征的类具有相同的类型(换句话说,具有统一子节点的树节点)。
In theory TreeNode2
is a particular case of TreeNode1
: 从理论上讲TreeNode2
是一个特殊情况TreeNode1
:
trait TreeNode2 extends TreeNode1[this.type] {...}
But Scala will not compile TreeNode2
with such an extension, because this.type
can not be used in such way, although there are no any inconsistencies with its working in runtime. 但是Scala不会使用这种扩展来编译TreeNode2
,因为不能以这种方式使用this.type
,尽管它在运行时的工作没有任何矛盾。
How can I get around this situation? 我如何解决这种情况? Or Scala do not offer such poorly used mechanism? 还是Scala不提供这种使用不良的机制?
The reason I need this construction is the following: 我需要这种构造的原因如下:
I have another trait that requires TreeNode1
to be mixed in. I also have some class that mixes TreeNode1
with quite another children type. 我还有另一个需要混合TreeNode1
特性。我也有一些类将TreeNode1
与另一TreeNode1
类型混合在一起。 But I also have several classes which have the same type as they are: 但是我也有几个类具有相同的类型:
class SomeTreeNode extends TreeNode1[SomeTreeNode]
So it will look prettier if I use TreeNode2
for it: 因此,如果我使用TreeNode2
,它将看起来更漂亮:
class SomeTreeNode extends TreeNode2
Implementing the same logic. 实现相同的逻辑。 But for using TreeNode2
should be a case of TreeNode1
, which it actually is, but Scala doesn't agree with me. 但对于使用TreeNode2
应的情况下TreeNode1
,它实际上是,但斯卡拉不同意我的看法。
PS At least it is wondering as theoretical question about Scala, not for a wide practical use. PS:至少,这是关于Scala的理论性问题,而不是广泛的实际使用。
its children have the same type as the class the current trait is mixed 它的子代与当前特质混杂的班级具有相同的类型
No. This is a common misunderstanding. 不。这是一个常见的误解。 this.type
is the singleton type of this
; this.type
是的单类型this
; ie the type whose only two values are this
and null
. 即只有两个值是this
和null
。 All children of a TreeNode2
instance must be the same instance. TreeNode2
实例的所有子代都必须是同一实例。
To answer the other part of your question, one option is to make S
a type member instead of a type parameter: 要回答问题的另一部分,一个选择是使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]
}
(so-called Aux
pattern), but whether this works for you depends on how they are used. (所谓的Aux
模式),但是这对您是否有效取决于它们的使用方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.