我想定义一个类层次结构,其中约有100 case classes
派生自公共基础。这些类型描述了AST层次结构中的节点,如this one。我想做一些事情:
trait Base {
def doCopy: Base
}
trait CloneSelf[T <: CloneSelf[T]] extends Base {
self: T =>
def copy(): T
override def doCopy: T = copy()
}
case class CaseA(a: String) extends Base with CloneSelf[CaseA]
case class CaseB(b: Int) extends Base with CloneSelf[CaseB]
这会产生错误,因为copy
的存在会阻止case classes
定义自动副本。有没有办法如何实现&#34;克隆&#34; doCopy
这样使用copy
的自动case classes
?
答案 0 :(得分:1)
我想定义一个类层次结构,其中包含大约100个从公共基础派生的案例类。
请不要这样做,你绝对应该找到一个模式来避免它!如果你想这样做......试试ducktyping:
trait CloneSelf[T <: {def copy(): T}] {
self: T =>
override def doCopy: T = copy()
}
我现在无法测试,所以这可能不会编译,但你可以自己弄清楚这个概念!
编辑:
为什么有100个子类是邪恶的:想象你在基类中执行一个更改,例如将其名称从Base
更改为BaseCloning
- &gt;你必须在每个儿童班(100次改变)中改变它。
如何避免这种情况取决于您对类的操作,检查 creationnal 和结构模式:factory,builder,prototype,flyweight,composite .. 。如果我改变基类中的某些东西,总是要考虑&#34;我将拥有多少工作?它会影响所有孩子吗?&#34;
答案 1 :(得分:0)
我发现在每个doCopy
中定义case class
实际上比定义从CloneSelf
继承的每个类要少。代码如下所示:
trait Base {
def doCopy: Base
}
case class CaseA(a: String) extends Base {
def doCopy = copy()
}
case class CaseB(b: Int) extends Base {
def doCopy = copy()
}
我很惊讶地发现,如果在重写方法上没有显式类型,则编译器会推断出类型,因此CaseA("a").doCopy
的静态类型与CaseA("a").copy()
的静态类型相同,即{{1} },而不是CaseA
。为每个Base
添加显式类型可能更为明显,但与仅将相同行复制粘贴到每个类中相比,这将需要更多工作。这并不重要 - 当我通过case class
类型进行复制时,我也可以使用case class
。只有当我需要copy()
Base
时才需要doCopy
,因此声明它def doCopy: Base = copy()
会造成很小的伤害。