3

ミックスインを使用してモジュール式に「強化」したい型の FAMILY があります。例えば:

trait Family {
  self =>
  trait Dog {
    def dogname:String
    def owner:self.Person
  }
  trait Person {
    def name:String
    def pet:self.Dog
  }
}

trait SerializableFamily extends Family {
  trait Dog extends super.Dog {
    def toSimpleString:String = "Dog(" + dogname + ")"
  }
  trait Person extends super.Person {
    def toSimpleString:String = "Person(" + name + ") and his pet " + pet.toSimpleString
  }
}

trait SerializableFamily2 extends Family {
  trait Dog extends super.Dog {
    def toLoudString:String = "Dog(" + dogname.toUpperCase + ")"
  }
  trait Person extends super.Person {
    def toLoudString:String = "Person(" + name.toUpperCase + ") and his pet " + pet.toLoudString
  }
}

ただし、上記は機能しません ( Scala 2.9.1 )。最後の式がコンパイルに失敗しました ( pet.toSimpleString)。

これは、私が試したいくつかの中から選んだランダムな戦略です: 自己型付け、抽象型、スーパー [...] など。

最終的には、次のようなことができるようになりたいです。

val family = new Family with SerializableFamily with TraversableFamily with FooFamily {}

各 mixin は、一連の連携メソッドをファミリ内の 1 つ以上の型に追加します。

これは、暗黙的なラッパー、パターン マッチング ベースのビジターなどを使用して解決された一般的なパターンです。しかし、これは通常の mixin パターンの再帰的な適用にすぎないため、それを達成するためのより簡単な方法があるのではないかと思います。

4

1 に答える 1

5

あなたの場合のエラーは予想されます。ミックスインのand は andDogをオーバーライドPersonないため、それはまだ を参照しています。 DogPersonFamilyself.PersonFamily.Person

これはあなたが望むものに近いかもしれません

trait Family {
  // type DogType = Dog won't work because then two different mixins 
  // have incompatible DogType implementations
  type DogType <: Dog
  type PersonType <: Person

  trait Dog {
    def dogname:String
    def owner:PersonType 
  }
  trait Person {
    def name:String
    def pet:DogType 
  }
}

trait SerializableFamily extends Family {
  type DogType <: Dog
  type PersonType <: Person

  trait Dog extends super.Dog {
    def toSimpleString:String = "Dog(" + dogname + ")"
  }
  trait Person extends super.Person {
    def toSimpleString:String = "Person(" + name + ") and his pet " + pet.toSimpleString
  }
}

しかし、その後、次のような厄介なものがあります

new Family with SerializableFamily with TraversableFamily with FooFamily {
  type DogType = super[SerializableFamily].Dog with super[TraversableFamily].Dog with super[FooFamily].Dog
}
于 2013-02-05T09:58:02.480 に答える