[英]Scala self type and this.type in collections issue
我試圖在scala中圍繞抽象和顯式自我類型。 讓我們考慮這個例子:我想為可擴展樹創建一個簡單的基礎:
trait Tree {
def children: Iterable[Tree]
def descendants: Iterable[Tree] = { val dv = children.view; dv ++ (dv.flatMap { _.children }) }
}
但是,我希望能夠使用某些方法擴展樹節點並使用以下方法: tree.children foreach { _.newMethod() }
為此,我嘗試過:
A. this.type:失敗
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 })
}
}
根據我的理解,由於路徑特定類型不匹配,根本不起作用。
C.類型params(泛型):好的
trait Tree[+Node <: Tree[Node]] {
def children: Iterable[Node]
def descendants: Iterable[Node] = {
val dv = children.view
dv ++ (dv.flatMap { _.children })
}
}
工作正常,但在派生類中維護不太好。
任何想法如何使前兩個變體工作沒有大量的代碼?
另外,使用this.type我遇到了實現問題。
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 {
// ...
}
謝謝!
如果沒有真正理解你遇到的問題(C),你可以嘗試(B)的變體:
trait Tree {
type Node <: Tree
def children: Iterable[Tree#Node]
def descendants: Iterable[Tree#Node] = {
val dv = children.view
dv ++ (dv.flatMap { _.children })
}
}
這避免了您的路徑特定類型問題。 順便說一下,你應該看看http://www.assembla.com/spaces/scala-graph/wiki
最后,我已經討論了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)但具有明確的自我類型。 這使得有機會在其他方法中使用this
(比如方法find(path: String): Option[Node]
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.