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

斯卡拉 – 搞砸了特质线性化?

发布时间:2020-12-16 10:02:23 所属栏目:安全 来源:网络整理
导读:这是一个让我头疼的特质线性益智游戏.我基本上键入了Node,它定义了equals和hashCode,以便与其他节点进行比较.我有一个Selector类型,它可以包含Node以及额外的数据,因此有自己的equals和hashCode可以与其他选择器进行比较. 现在我有一个Standalone类型,它结合
这是一个让我头疼的特质线性益智游戏.我基本上键入了Node,它定义了equals和hashCode,以便与其他节点进行比较.我有一个Selector类型,它可以包含Node以及额外的数据,因此有自己的equals和hashCode可以与其他选择器进行比较.

现在我有一个Standalone类型,它结合了Node和Selector,但是我得到了与equals和hashCode不一致的(?)linearisation:

trait Selector { override def hashCode = 1 }
trait Event extends Selector

trait Node { override def hashCode = 2 }
trait Standalone extends Node with Event

当我从Event或Standalone扩展时,现在一切都很好(调用更具体的hashCode 1):

object Single1 extends Event
Single1.hashCode // 1 -- ok

object Single2 extends Standalone
Single2.hashCode // 1 -- ok

如果我按此顺序从两者扩展,那也没关系:

object Compound1 extends Standalone with Event
Compound1.hashCode // 1 -- Ok

但是当我这样做时它会搞砸:

object Compound2 extends Event with Standalone
Compound2.hashCode  // 2 -- no!!!!!!!!

我做了一点.dot图(mixins从左到右排序):

所以,如果我正确理解linearisation rules,我应该总是使用Selector实现的hashCode.对这种行为的唯一解释是,存在某种贪婪/深度优先的事情……?

此外,如果有一种技术我可以用来确保每当Standalone混入时,确保Selector取代Node(除了将Seals和hashCode从Selector复制到Standalone),这将是非常值得赞赏的.

这与Scala 2.9.2有关.

解决方法

这种事情最好去Spec.
该算法在5.1.2类线性化中描述

换句话说,C类的线性化是C,然后是从最右边的项开始扩展的东西的线性化.然后是最后一步,删除线性化中的重复项,只保留最右边的那些.

所以在你的Compound1示例中(忽略像AnyRef这样的内置函数):
L(化合物1)=化合物1 L(事件)L(独立)
L(事件)=事件L(选择器)
L(选择器)=选择器
L(独立)=独立L(事件)L(节点)
L(节点)=节点
把它放在一起:
L(Compound1)= Compound1事件选择器独立事件选择器节点
删除重复项:
Compound1独立事件选择器节点

对于Compound2,它最终是:
Compound2独立节点事件选择器

至于另一个问题,我认为最简单的方法是覆盖Standalone中的方法并在超类中调用所需的方法.

trait Standalone extends Node with Event { override def hashCode = super[Event].hashCode }

假设这不是你所说的“复制”.

(编辑:李大同)

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

    推荐文章
      热点阅读