为什么Scala案例类复制方法仅使用案例类中定义的变量进行参数化?
基于Q& A的问题:
Case class copy does not maintain state of an inherited trait
简短摘要 - 当使用字段定义trait并使用case类扩展时,case类上的copy
将仅使用case类中定义的变量创建新的类实例,而不使用扩展特征。 / p>
trait A {
var list: List[Int] = List()
def add(element: Int) = {
list = element :: list
}
}
case class B(str: String) extends A {
val b = B("foo")
println("B1: " + b.list)
b.add(1)
b.add(2)
b.add(3)
println("B2: " + b.list)
val b2 = b.copy(str = "bar")
println("B3: " + b.list)
println("B4: " + b2.list)
}
此处,B4: ()
将为空,而B3:(3,2,1)
答案 0 :(得分:2)
因为没有合理的方法可以始终如一地做你想做的事。
对于您的示例,copy
的生成代码可能是
def copy(str: String = this.str, list: List[Int] = this.list): B = {
val newB = B(str)
newB.list = list
newB
}
足够好。现在,如果您将list
更改为私有,或val
而不是var
,会发生什么?在这两种情况下newB.list = ...
都不会编译,编译器应生成什么代码?
答案 1 :(得分:0)
如果你真的想在复制后保留list
的值(考虑到我在OP的评论中提到的可变性问题),你可以编写自己的copy
方法。
case class B(str: String) extends A {
def copy(str: String = this.str, list: List[Int] = this.list): B = {
val newB = B(str)
list.reverse.foreach(newB.add)
newB
}
}