我正在尝试制作一个特性,我可以将它混合到一个类中,将其定义为树节点。找到一种优雅的方式来解决这个问题。
以下内容无法正常工作,因为this.type会在您分配父级时导致类型不匹配
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]
}
任何更严格方法的想法?
答案 0 :(得分:3)
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 }
答案 1 :(得分:2)
您可以添加自我类型以避免演员:
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)
}