如何覆盖类型成员并添加更多的混入(mixins)到其中

4

举个例子来解释会更容易理解。我有一个定义类型RecBase特质:

trait A
trait B
trait C

trait Base {
  type Rec <: A
  def foo(r: Rec): Rec = ???
}

现在我想为Base创建“增强器”,使用抽象重写修饰符在重写的方法上添加一些功能,同时使类型Rec更具体(取决于增强器执行的具体任务):
trait Enricher1 extends Base {
  override type Rec <: Base#Rec with B
  abstract override def foo(r: Rec): Rec = ??? // uses super.foo
}

trait Enricher2 extends Base {
  override type Rec <: Base#Rec with C
  abstract override def foo(r: Rec): Rec = ??? // uses super.foo
}

问题是:我无法混合我的增强剂:
trait Concrete extends Base
trait Custom extends Concrete with Enricher1 with Enricher2

编译器拒绝了这个,基本上是说在Enricher1Enricher2中类型为Rec的不兼容,我非常同意他的说法。请注意,使用单个enricher可以编译。
因此,我们需要改写成:
override type Rec <: Base#Rec with B

我更倾向于这样说:给我与Rec已有类型相同的内容,但加上with X。我尝试过了。
override type Rec <: super.Rec with B

但是编译器也会报错,显示“循环别名”,我该怎么办?

我该如何解决这个问题?


赞同编译器的意见:这总是一个好习惯 :) - Akos Krivachy
你试过在type前面移除override吗?让它简单地变成type Rec <: C。这样应该允许你混合所有的 traits。 - Arseniy Zhizhelev
@ArseniyZhizhelev,不,它无法编译。目标是在每个混入的特质层中添加新的“with X”。 - Tvaroh
@ArseniyZhizhelev,你不能使用self类型调用祖先(super)方法。self.foo只是foo,而不是super.foo。这只有在抽象覆盖(abstract override)的情况下才可能实现。 - Tvaroh
看起来我需要一种类型的“抽象覆盖”,但在Scala中不可能实现。也许,我应该重新考虑我的设计。 - Tvaroh
显示剩余2条评论
1个回答

0

如果我正确理解你想做的事情,这是我认为可以做的:

trait A
trait B
trait C

trait Base {
  type Rec <: A
   def foo(r: Rec): Rec = ???
}

trait Enricher1 extends Base {
  override type Rec <: Base#Rec with C
   abstract override def foo(r: Rec): Rec = ??? // uses super.foo
}
trait Enricher2 extends Enricher1 {
  override type Rec <: Enricher1#Rec with B
  abstract override def foo(r: Rec): Rec = ??? // uses super.foo
}
trait Concrete extends Base
trait Custom extends Concrete with Enricher2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接