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

scala – 继承保持类型的特征

发布时间:2020-12-16 18:11:08 所属栏目:安全 来源:网络整理
导读:我对 Scala很新,并且仍然对其复杂的类型系统感到困惑. 我尝试解决以下问题.我想设计属于可变双向链表(以及更复杂的数据结构,如堆)的成员的类.当然,我的目标是能够在恒定的时间内从数据结构中删除对象. 我设计了以下特质: trait DLLMember { var next: DLLMe
我对 Scala很新,并且仍然对其复杂的类型系统感到困惑.

我尝试解决以下问题.我想设计属于可变双向链表(以及更复杂的数据结构,如堆)的成员的类.当然,我的目标是能够在恒定的时间内从数据结构中删除对象.

我设计了以下特质:

trait DLLMember {
  var next: DLLMember = this
  var prev: DLLMember = this

  ...
}

使用一些其他方法从列表中添加和删除对象.

问题是,当我在实际上课时,说:

class IntInDL(val v: Int) extends DLLMember

在解析我的列表时,IntInDL.next会返回一个DLLMember类型而不是IntInDL,我必须强制转换它来检索值:这不好…

有没有办法利用Scala的类型系统来保持我的工作类型安全?

解决方法

这是一个小迂回,但以下应该工作:

trait DLLMember[T >: Null <: DLLMember[T]] { self : T =>
  var next: T = this
  var prev: T = this
  ...
}

class IntInDL(val v: Int) extends DLLMember[IntInDL]

var i = new IntInDL(3)
println(i.next.v) //prints 3
i.next = null //is valid
i.next = new IntInDL(1) //is valid

从本质上讲,这里发生的是你用自我说:T =>类型参数T必须是应用此特征的类的超类.当你在IntInDL中使用trait时,现在知道next和prev变量必须是IntInDL的某个子类型,因为你提供了它作为type参数.因此,您可以直接使用其成员,而无需进行强制转换.

如果您提供了一些不属于层次结构的其他任意类型,则类IntInDL(val v:Int)扩展DLLMember [String],例如,它将无法编译.

(编辑:李大同)

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

    推荐文章
      热点阅读