5

I've been playing with the cake pattern and there's something I don't fully understand.

Given the following common code:

trait AServiceComponent {
  this: ARepositoryComponent =>
}

trait ARepositoryComponent {}

the following way of mixing them works

trait Controller {
  this: AServiceComponent =>
}

object Controller extends 
  Controller with 
  AServiceComponent with 
  ARepositoryComponent

But the following does not

trait Controller extends AServiceComponent {}

object Controller extends
  Controller with
  ARepositoryComponent

with error:

illegal inheritance; self-type Controller does not conform to AServiceComponent's selftype AServiceComponent with ARepositoryComponent

Shouldn't we be able to "push" dependencies up in the hierarchy if we know that they will be common for all subclasses?

Shouldn't the compiler allow for Controller to have dependencies, as long as it's not instantiated without resolving them?

4

1 回答 1

4

这是遇到相同问题的一种稍微简单的方法:

scala> trait Foo
defined trait Foo

scala> trait Bar { this: Foo => }
defined trait Bar

scala> trait Baz extends Bar
<console>:9: error: illegal inheritance;
 self-type Baz does not conform to Bar's selftype Bar with Foo
       trait Baz extends Bar
                         ^

问题是编译器希望您在子类型定义中重复自类型约束。在我的简化案例中,我们会写:

trait Baz extends Bar { this: Foo => }

在您的中,您只需要进行以下更改:

trait Controller extends AServiceComponent { this: ARepositoryComponent => }

这个要求是有道理的——希望有人Controller在不查看它继承的类型的情况下能够了解这种依赖关系是合理的。

于 2014-03-26T14:04:08.287 回答