3

我有一系列类型,我想使用 mixins 模块化“丰富”。例如:

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 都会为家族中的一个或多个类型添加一组协作方法。

这是一种常见的模式,我已经看到通过使用隐式包装器、基于模式匹配的访问者等来解决。但由于它只是常规 mixin 模式的递归应用,我想知道是否有更简单的方法来实现它。

4

1 回答 1

5

您的案例中的错误是预期的,因为Dogand Personin mixins 不会覆盖 Dogand Personin Family,因此self.Person仍然指Family.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 回答