私は持っている:
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 つの質問:
- 混在制限線で存在型を直接定義することはできません。私は得る:
; 期待されていましたが、「forSome」が見つかりました。
これを回避する方法はありますか?
実際には、
PetCareInfo
のforSome
制限+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
ます。:(