Scala 中的个案继承 [英] Case to case inheritance in Scala
问题描述
我有一个抽象类,我扩展并创建了许多案例类.现在我想复制那些只是改变第一个参数的案例类的实例,所以我使用案例类的 copy
方法.
I have an abstract class which I extend and make numerous case classes. Now I want to copy instances of those case classes just changing first parameter, so I use case class' copy
method.
由于我必须对从通用抽象类扩展而来的所有案例类都这样做,而不是对所有案例类都这样做,因此我尝试使其通用并将抽象类设为案例类.
Since I have to do this for all case classes that have been extended from common abstract class, rather than doing it for all, I tried to make it general and made the abstract class a case class.
然后 Scala 给了我这个:
Then Scala gives me this:
case class Octopus 有 case 祖先 Organism,但禁止 case-to-case 继承.为了克服这个限制,使用提取器在非叶节点上进行模式匹配.
case class Octopus has case ancestor Organism, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
代码:
abstract class Organism(legs: Int)
case class Octopus(override val legs: Int, weight: Double, ...)
case class Frog(override val legs: Int, ...)
def clone(o: Organism) = o.copy(legs = -1)
这就是我想做的.但是如果我不能使 clone
方法工作,那么我将不得不对 Octopus
和 & 进行复制.青蛙
.
This is what I want to do. But if I can't make the clone
method work, then I will have to do copying for both Octopus
& Frog
.
任何建议,以减少这种冗长?
Any suggestions, to decrease this verbosity?
推荐答案
您不能对案例类的 copy
方法进行一般抽象.我建议使用 Shapeless 或 Monocle 的镜片:
You can't abstract over case class' copy
methods generically. I'd suggest using Lenses from Shapeless or Monocle:
trait Organism { def legs: Int }
// monocle @Lenses uses a macro to generate lenses
@Lenses case class Octopus(override val legs: Int, weight: Double, ...)
extends Organism
@Lenses case class Frog(val legs: Int, ...) extends Organism
def clone[O <: Organism](o: O, legsLens: Lens[O, Int]): O =
legsLens.set(-1)(o)
val myOctopus = Octopus(8, 2.4, ...)
val myFrog = Frog(2, ...)
// use the generated Lenses
val cloneOctopus: Octopus = clone(myOctopus, Octopus.legs)
clone(myFrog, Frog.legs)
这篇关于Scala 中的个案继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!