【问题标题】:Scala mixin Node traitScala mixin 节点特征
【发布时间】:2014-05-30 10:15:41
【问题描述】:

我正在尝试制作一个特征,我可以将其混合到一个类中以将其定义为树节点。找到一种优雅的方式来做到这一点是有问题的。

以下内容不起作用,因为 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]
}

有更严格的方法的想法吗?

【问题讨论】:

    标签: scala mixins


    【解决方案1】:
    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 }
    

    【讨论】:

      【解决方案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)
      }
      

      【讨论】:

      • 你可能还需要一个自我类型,self: T =&gt;
      • 谢谢;你是对的。虽然我不再确定这是否比添加自我类型和使用普通的T 更好。
      • 而且由于我的版本中的类型很难看,“没有更好”意味着“明显更糟”..
      猜你喜欢
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多