Scala mixin Node trait



我试图使一个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)
}

最新更新