我想圍繞抽象和明確的自我類型在斯卡拉我的頭。 讓我們考慮這個例子: 我想創建一個可擴展的樹這麼簡單一個基地:斯卡拉自我類型和this.type在集合問題
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:FAIL
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(仿製藥):OK
trait Tree[+Node <: Tree[Node]] {
def children: Iterable[Node]
def descendants: Iterable[Node] = {
val dv = children.view
dv ++ (dv.flatMap { _.children })
}
}
工程確定,但不是那麼好派生類中維護。
任何想法如何使第一個兩個變種沒有噸代碼工作?
另外,有了這個類型,我遇到了執行問題。
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 {
// ...
}
謝謝!
啊是的。 「Scala沒有MyType」問題。 – 2012-02-08 19:11:14
正如你所看到的,我在SO中查看了這個,並嘗試了提議的變體。它適用於非常簡單的構造(比如Martin的論文中的'c.incr()。decr()'示例),但對於集合則不適用。 – tuxSlayer 2012-02-08 19:18:26
是的。得到了點爲什麼看完你的討論後在這裏http://www.scala-lang.org/node/6649, 謝謝 – tuxSlayer 2012-02-08 22:26:30