我试图使一个trait,我可以混合到一个类,将其定义为一个树节点。找到一种优雅的方法来做这件事是有问题的。
下面的代码不起作用,就像下面这样。类型导致类型不匹配,当您分配父
trait Node {
def parent:Option[this.type]
def root:this.type =
parent.fold(this)(_.root)
}
这种方法是有效的,但是T值可能会被漏赋,并且转换非常难看。
trait Node[T <: Node[T]] {
def parent:Option[T]
def root:T =
parent.fold(this)(_.root).asInstanceOf[T]
}
有更严格的方法吗?
trait Node[+T] {
def parent: Option[Node[T]]
def root: Node[T] = parent.fold(this)(_.root) // root is node as well, isn't it?
}
class Foo extends Node[Foo] { def parent = None }
可以添加一个self-type来避免强制类型转换:
trait Node[T <: Node[T]] { self: T =>
def parent: Option[T]
def root: T = parent.fold(this)(_.root)
}
您还可以返回T with Node[T]
而不是普通的T
,但我不确定这是否提供了超越自我类型给您的真正好处:
trait Node[T <: Node[T]] { self: T =>
def parent: Option[T with Node[T]]
def root: T with Node[T] = parent.fold(this)(_.root)
}