5

ケーキのパターンで遊んでいて、よくわからないことがあります。

次の共通コードが与えられます。

trait AServiceComponent {
  this: ARepositoryComponent =>
}

trait ARepositoryComponent {}

それらを混合する次の方法が機能します

trait Controller {
  this: AServiceComponent =>
}

object Controller extends 
  Controller with 
  AServiceComponent with 
  ARepositoryComponent

しかし、以下はそうではありません

trait Controller extends AServiceComponent {}

object Controller extends
  Controller with
  ARepositoryComponent

エラーあり:

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

依存関係がすべてのサブクラスに共通であることがわかっている場合、依存関係を階層内で「押し上げる」ことができるはずではありませんか?

Controller依存関係を解決せずにインスタンス化しない限り、コンパイラは依存関係を持つことを許可すべきではありませんか?

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 に答える