scala – 在可堆叠特征模式中覆盖抽象类型成员
发布时间:2020-12-16 19:25:16 所属栏目:安全 来源:网络整理
导读:假设我们想要定义如何在某些数据上累积结果的方法: case class Data(x: Int,y: Int) 我们定义了一个特征: trait Accumulator { type R def add(acc: R,d: Data): R def zero: R} 一个简单的实现: trait XAccumulator extends Accumulator { type R = Int
假设我们想要定义如何在某些数据上累积结果的方法:
case class Data(x: Int,y: Int) 我们定义了一个特征: trait Accumulator { type R def add(acc: R,d: Data): R def zero: R } 一个简单的实现: trait XAccumulator extends Accumulator { type R = Int def add(acc: Int,d: Data) = acc + d.x def zero = 0 } 我想使用stackable-trait模式来使用多个这些简单的累加器: trait TraceYAccumulator extends Accumulator { abstract override type R = (Seq[Int],super.R) // fails: // `abstract override' modifier not allowed for type members def add(acc: R,d: Data) = { val r = super.add(acc._2,d) (acc._1 :+ d.y,r) } def zero = (Seq.empty[Int],super.zero) } 显然我不允许覆盖抽象类型的成员.如何使用可堆叠特征模式更改重写方法的结果类型? 我的第二种方法是使用类型参数: trait Accumulator[R] { def add(acc: R,d: Data): R def zero: R } trait XAccumulator extends Accumulator[Int] { def add(acc: Int,d: Data) = acc + d.x def zero = 0 } 但现在变得非常奇怪: trait TraceYAccumulator[T] extends Accumulator[(Seq[Int],T)] { this: Accumulator[T] => def add(acc: (Seq[Int],T),d: Data): (Seq[Int],T) = { val r = this.add(acc._2,d) // fails: overloaded method value add with alternatives: // (acc: (Seq[Int],d: Data)(Seq[Int],T) <and> // (acc: _14695,d: Data)_14695 cannot be applied to (T,Data) (acc._1 :+ d.y,r) } def zero: (Seq[Int],T) = (Seq.empty[Int],this.zero) } 由于超类和混合类具有相同的方法名称(显然),我们不能引用正确的方法.我唯一的选择是使用作文吗? 我怎样才能堆叠这样的操作? 解决方法
第一种方法有一个基本的理论问题:
假设我们被允许写这些特征.然后考虑以下事项: val acc = new XAccumulator with TraceYAccumulator val xacc = acc: XAccumulator 由于xacc是XAccumulator,我们知道x.R =:= Int.糟糕! 第二种方法存在实现问题:您无法从同一特征的不同实例继承. illegal inheritance; anonymous class $anon inherits different type instances of trait Accumulator: Accumulator[Int] and Accumulator[(Seq[Int],Int)] 因此,组合(或者某些类型类hackery)似乎是唯一的选择. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Angular1、Angular2常用小方法(持续添加。。。)
- scala – 关键字“implicit”在放在lambda表达式参数前是什
- angular – 可以更改离子导航栏内的离子标题大小?
- angular – 如何将样式类添加到p-dataTable行
- active-directory – 哪些身份管理产品适合中小型企业?
- Windows线程调度策略(超详细)
- 如何将角度2中的日期转换为’yyyy-MM-dd’格式
- WebService大讲堂之Axis2(3):使用services.xml文件发布Web
- unix – 我可以确定终端是否解释C1控制代码?
- 在JAX-WS 中实现多个Service间会话保持( 1 )