17

実際の派生型と一致する必要があるジェネリック型変数を宣言するための一般的なJavaイディオム(Enumたとえば、に見られる)があります。

class Enum<E extends Enum<E>> {
...
}

または、必要に応じて、より一般的な引数:

abstract class Foo<T, Actual extends Foo<T, Actual>> {
    //now we can refer to the actual type
    abstract Actual copy();
}
class Concrete<T> extends Foo<T, Concrete<T>> {
    Concrete<T> copy() {...}
}

物事は非常にすぐに冗長になる可能性があるので、Scalaは上記の例の直訳よりも優れたものを持っているのではないかと想像しました。

これを達成するためのよりエレガントな方法はありますか?

4

1 に答える 1

11

別の定式化は、抽象型メンバーを使用することです。

trait Foo { self => 
  type A <: Foo {type A = self.A}
}

あなたの例で:

trait Foo { self =>
  type T
  type Actual <: Foo {type T = self.T; type Actual = self.Actual}
}

trait Concrete extends Foo { self =>
  type T
  type Actual = Concrete {type T = self.T}
}

この再定式化は、トレイト/クラス宣言ではそれほど優れていませんが、トレイト/クラスを使用する場合は、はるかに簡潔になる可能性があります。(そして私が知る限り、再帰型を再定式化する別の方法はありません)。

于 2013-01-30T23:08:45.797 に答える