11
私は、クラス自体のインスタンスを返すメソッドを持つジェネリック特性を作成しようとしています。明示的な戻り値の型なしスカラジェネリックthis.type
trait SomeGenericTrait[T]{
def withData(newData : Seq[T]) : this.type
}
case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
override def withData(newData : Seq[Int]) : SomeImpl = copy(data = newData)
}
error: overriding method withData in trait SomeGenericTrait of type(newData: Seq[Int])SomeImpl.this.type; method withData has incompatible type
:たとえば実装withData
の戻り値がSomeImpl
ですが、トレイトのメソッド宣言に基づいて予想される戻り値の型がSomeImpl.this.type
あるので
case class SomeImpl(data : Seq[Int]) extends SomeGenericTrait[Int] {
override def withData(newData : Seq[Int]) = copy(data = newData)
}
error: type mismatch;
found : SomeImpl
required: SomeImpl.this.type
これはコンパイルに失敗します。
これは機能するように私はtraitメソッド宣言の戻り値の型を変更する必要がどのように知っていますか?私が持っているより一般的な使用例は、ケースクラスのcopy
メソッドを拡張する一般的な特性を通して公開する方法です。私はこれを明確に明言していない可能性があることを知っている、私は何かを明確にすべきかどうか私に知らせる。 - 特定のものの種類
trait SomeGenericTrait[T, X] {
def withData(newData: Seq[T]): X
}
case class SomeImpl(data: Seq[Int]) extends SomeGenericTrait[Int, SomeImpl] {
override def withData(newData: Seq[Int]): SomeImpl = copy(data = newData)
}
this.type
はシングルトンタイプである:Scalaの2.10.0
(このパターンは[CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#In_other_languages)として知られています) – Rich
つまり、 'this.type'は' this'だけを返すことができますが、 'copy'で作成された同じクラスの新しいインスタンスを返すことはできません。 –
もう少し厳密な宣言は、Xをその形質のサブクラスに限定する 'trait SomeGenericTrait [T、+ X <:SomeGenericTrait [T、X]]'となります。 –