类型参数中的Scala特征`this.type` [英] Scala trait `this.type` in type parameter

查看:30
本文介绍了类型参数中的Scala特征`this.type`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看这两个简单的特征:

Have a look at these two simple traits:

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

(不是最好的命名,重命名只是为了简短.)
TreeNode1 定义了一个树节点及其子节点访问,指向它们的类型 S.
TreeNode2 定义相同,但其子节点具有与当前特征混合的类相同的类型(换句话说,具有统一子节点的树节点).

(Not best naming, renamed them just to be brief.)
TreeNode1 defines a tree node with its children access, pointing their type 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).

理论上TreeNode2TreeNode1的一个特例:

In theory TreeNode2 is a particular case of TreeNode1:

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

但是Scala不会用这样的扩展编译TreeNode2,因为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 没有提供这种不好用的机制?

How can I get around this situation? Or Scala do not offer such poorly used mechanism?

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

我有另一个特征需要混合 TreeNode1.我还有一些类将 TreeNode1 与另一种子类型混合.但我也有几个类,它们的类型与它们相同:

I have another trait that requires TreeNode1 to be mixed in. I also have some class that mixes TreeNode1 with quite another children type. But I also have several classes which have the same type as they are:

class SomeTreeNode extends TreeNode1[SomeTreeNode]

所以如果我使用 TreeNode2 它会看起来更漂亮:

So it will look prettier if I use TreeNode2 for it:

class SomeTreeNode extends TreeNode2

实现相同的逻辑.但是对于使用 TreeNode2 应该是 TreeNode1 的情况,它实际上是,但 Scala 不同意我的看法.

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.

附言至少它是关于 Scala 的理论问题,而不是广泛的实际用途.

P.S. At least it is wondering as theoretical question about Scala, not for a wide practical use.

推荐答案

它的子类与当前 trait 混合的类具有相同的类型

its children have the same type as the class the current trait is mixed

没有.这是一个普遍的误解.this.typethis 的单例类型;即 只有两个值是thisnull.TreeNode2 实例的所有子节点必须是同一个实例.

No. This is a common misunderstanding. this.type is the singleton type of this; i.e. the type whose only two values are this and null. All children of a TreeNode2 instance must be the same instance.

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

To answer the other part of your question, one option is to make S a type member instead of a type parameter:

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 模式),但这是否适合您取决于它们的使用方式.

(so-called Aux pattern), but whether this works for you depends on how they are used.

这篇关于类型参数中的Scala特征`this.type`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆