加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

收集问题中的Scala自我类型和this.type

发布时间:2020-12-16 08:51:39 所属栏目:安全 来源:网络整理
导读:我试图在 scala中围绕抽象和显式的自我类型. 让我们考虑这个例子: 我想为可扩展树创建一个简单的基础: trait Tree { def children: Iterable[Tree] def descendants: Iterable[Tree] = { val dv = children.view; dv ++ (dv.flatMap { _.children }) }} 但
我试图在 scala中围绕抽象和显式的自我类型.
让我们考虑这个例子:
我想为可扩展树创建一个简单的基础:

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:失败

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(泛型):好的

trait Tree[+Node <: Tree[Node]] {

    def children: Iterable[Node]

    def descendants: Iterable[Node] = {
       val dv = children.view
       dv ++ (dv.flatMap { _.children })
    }
}

工作正常,但在派生类中维护不太好.

任何想法如何使前两个变体工作没有大量的代码?

另外,使用this.type我遇到了实现问题.

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 {
  // ...
}

谢谢!

解决方法

如果没有真正理解你遇到的问题(C),你可以尝试(B)的变体:

trait Tree {
    type Node <: Tree

    def children: Iterable[Tree#Node]  
    def descendants: Iterable[Tree#Node] = {
        val dv = children.view
        dv ++ (dv.flatMap { _.children })
    }
}

这避免了您的路径特定类型问题.
顺便说一句,你应该看看http://www.assembla.com/spaces/scala-graph/wiki

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读