我试图创建一个共享常用功能的类的层次结构,但只有在一起使用时才会这样。
sealed trait Farm[S <: Farm[S]] {
def animals: Int
def +(other: S) = animals + other.animals
}
case class SheepFarm(animals: Int) extends Farm[SheepFarm]
case class GoatFarm(animals: Int) extends Farm[GoatFarm]
object Tester {
val total = SheepFarm(5) + SheepFarm(6) // should return 11
val failure = SheepFarm(5) + GoatFarm(3) // should not compile
// should be able to use this pattern for functions outside the main classes
def add[S <: Farm[S]](one: S, two: S) = one + two
val total2 = add(SheepFarm(5), SheepFarm(6)) // should return 11
val failure2 = add(SheepFarm(5), GoatFarm(3)) // should not compile
}
到目前为止,这种笨拙的Foo[S <: Foo[S]]
构造是我发现这样做的唯一方法,这使得许多代码下游的可读性降低。有没有更优雅的方法来使这个模式起作用,所以我可以绕过Foo
s?
我尝试了隐式参数的各种排列,this.type
和类型参数,但到目前为止还没有运气。
谢谢!
答案 0 :(得分:4)
这是一个经典的&#34;自我类型&#34;许多解决方案存在问题,每个解决方案都有其自身的缺点。
关于此有几个资源和讨论,一个好的起点是this Jessica Kerr's blog post(另外,看看她在那里列出的更多资源)。
我曾经为使用白盒宏的问题找到了另一种解决方案。你可以找到它here。