Scala自我类型和collection.issue中的this.type [英] Scala self type and this.type in collections issue
问题描述
我正在尝试把自己的头放在scala中的抽象和显式自身类型上. 让我们考虑这个例子: 我想像这样简单地为可扩展树创建基础:
I'm trying to wrap my head around abstract and explicit self types in scala. Lets consider this example: I want to create a base for extensible tree as simple as this:
trait Tree {
def children: Iterable[Tree]
def descendants: Iterable[Tree] = { val dv = children.view; dv ++ (dv.flatMap { _.children }) }
}
但是,我希望能够使用某些方法扩展树节点并使用以下方法,例如:tree.children foreach { _.newMethod() }
However, I want to be able to extend tree nodes with some methods and use these methods like: tree.children foreach { _.newMethod() }
为此,我已经尝试过:
A.此类型:失败
trait Tree {
def children: Iterable[this.type]
def descendants: Iterable[this.type] = {
val dv = children.view
// FAIL: type mismatch; found : scala.collection.IterableView[com.abovobo.data.Tree,Iterable[_]] required: Iterable[Tree.this.type]
// dv ++ (dv.flatMap { _.children })
// OK:
dv.++[this.type, Iterable[this.type]](dv.flatMap[this.type, Iterable[this.type]]{ _.children })
}
}
工作变体非常笨拙.
B.抽象类型:失败
trait Tree {
type Node <: Tree
def children: Iterable[Node]
def descendants: Iterable[Node] = {
val dv = children.view
// FAIL: type mismatch; found : scala.collection.IterableView[com.abovobo.data.Tree#Node,Iterable[_]] required: Iterable[Tree.this.Node]
dv ++ (dv.flatMap { _.children })
}
}
由于我所理解的路径特定类型不匹配,因此根本无法工作.
Doesn't work at all due to path specific type mismatch as I understood.
C.键入params(泛型):确定
C. Type params (generics): OK
trait Tree[+Node <: Tree[Node]] {
def children: Iterable[Node]
def descendants: Iterable[Node] = {
val dv = children.view
dv ++ (dv.flatMap { _.children })
}
}
可以,但是在派生类中维护不太好.
Works OK, but not so good to maintain in derived classes.
有什么想法可以使前两个变体在没有大量代码的情况下工作?
Any ideas how to make first two variants working without a tons of code?
此外,使用this.type我在实现方面遇到了问题.
Also, with this.type I've run into problems with implementation.
trait BiDTree extends Tree {
def parent: Option[this.type]
}
// how to accept this param? Option[TreeImpl] doesn't work.
class TreeImpl(val parent: Option[???]) extends BiDTree {
// ...
}
谢谢!
推荐答案
At the end I've settled with what was proposed in this discussion http://www.scala-lang.org/node/6649:
trait Tree[+Node <: Tree[Node]] {
this: Node =>
def children: Iterable[Node]
def descendants: Iterable[Node] = {
val dv = children.view
dv ++ (dv.flatMap { _.children })
}
}
即变体(C),但具有明确的自我类型.这提供了在其他方法(例如方法find(path: String): Option[Node]
)中使用this
的机会.
I.e. variant (C) but with explicit self type. This gives a chance to use this
in other methods (say, method find(path: String): Option[Node]
).
这篇关于Scala自我类型和collection.issue中的this.type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!