0

私は持っている:

trait Pet[T <: Pet[T]] {    //disallows: Dog extends Pet[String]
  self: T =>                //disallows: Dog extends Pet[Monkey]
  def rename(s: String): T
  def name: String
}

Felineクラスを拡張するような特性はPet、次のように簡単に追加できます。

trait Feline[T <: Feline[T]] extends Pet[T] {
  self: T =>
  def pur : Unit = println("purrrr")
  def scratch: Unit
}

Petしかし、次のような自己型と混合する型を導入する場合:

trait PetCareInfo[T <: PetCareInfo[T]] {
    self: T with Pet[T] =>
    def registerPet: Unit
  }

エラーが発生します:

型引数 [T] はトレイト Pet の型パラメーター境界 [T <: Pet[T]] に準拠していません

私の理解では、これは自己型チェックインPetCareInfoが型A with Bを個別に調べ、そのため制限に失敗するためです。(これがバグなのか機能なのかはわかりません)

代わりに存在型を使用できます。

type TypeRestriction: Pet[A] forSome {type A}

trait PetCareInfo[T <: PetCareInfo[T]] {
    self: T with TypeRestriction => //mix-in restriction
    def registerPet: Unit
  }

そしてそれはちょっとうまくいくでしょう。2 つの質問:

  1. 混在制限線で存在型を直接定義することはできません。私は得る:

; 期待されていましたが、「forSome」が見つかりました。

これを回避する方法はありますか?

  1. 実際には、PetCareInfoforSome制限+Pet独自の制限は、私が持つことができないことを意味します:

    class Cat extends Pet[Dog] with PetCareInfo[Cat]

しかし、これに依存しない方法があれば知りたいですPet

更新

質問 2 では、既存の型制限を次のように変更できます。

type Restriction[T] = A with Pet[A] forSome {type A <: PetCareInfo[T]}

trait PetCareInfo[T <: PetCareInfo[T]] {
  self: Restriction[T] =>
  def registerPet: Unit
}

そして、それは問題を解決しているようです。Aただし、構造型が と同じになる保証はまだないTので、依然 に依存していPetます。:(

4

1 に答える 1