3

そのため、ここに少し不自然な例を示します。

trait MyTrait { 
  type T <: MyTrait
  val listOfT:List[T]
  def getFirst:T
  //def getOne:T = if( listOfT.length > 0 ) { getFirst } else { this }
}

class MyClass extends MyTrait {
  type T = MyClass
  override val listOfT:List[T] = List[MyClass](this)
  override def getFirst:T = listOfT.head
}

質問には次の 2 つの部分があります。

"type T = MyClass" を指定する代わりに、 MyClass の戻り値の型を "MyClass" にすることができる他の方法はありますか? 基本的に、サブクラスの実装を大幅に変更したり、型システムについて考えたりする必要なく、この特性をクラスに追加できるようにしたいと考えています...それ自体のメンバーを返すだけで、特性がサブタイプで共変です。これは意味がありますか?

MyTrait で、コメントを外した場合、getOne メソッドは「型の不一致:」というエラーを返します

戻り値の型を this.type に変更すると、反対の検出型/必須型の不一致が発生します。どちらの戻り値も実際には同じ型です (実際には同じオブジェクトです)。

この種の状況を処理する正しい方法は何ですか?

4

1 に答える 1

5

これは、あなたの望むことですか?

trait MyTrait[T <: MyTrait[T]] { self: T =>
  val listOfT: List[T]
  def getFirst: T
  def getOne: T = if (listOfT.length > 0) getFirst else self
}

class MyClass extends MyTrait[MyClass] {
  override val listOfT: List[MyClass] = List[MyClass](this)
  override def getFirst: MyClass = listOfT.head
}

type T = MyClass(戻り値の型を入れるだけでよい)を取り除きMyClass、 の定義でのコンパイル エラーを修正しますgetOne

于 2012-09-05T03:11:48.850 に答える