我遇到一个问题,其中在同一方法中在Scala中多次使用this
关键字实际上会失败。
由于代码库太大,我无法在此处复制问题,但是我会尽力显示问题。
我有一个类Foo,它具有可重写的方法fooMethod。在fooMethod内部,将生成三个属性值,并使用this
分别使用这些属性来更新当前类实例。但是,只有最后一个this
调用实际上设置了任何属性,前面的两个this
调用对该对象没有影响。
case class Foo(prop1: prop, prop2: prop2, prop3:prop3) extends FooParent {
override def fooMethod(){
val propA = gen()
val propB = gen()
val propC = gen()
this.withPropA(propA)
this.withPropB(propB)
this.withPropC(propC)
}
def withPropA(:propA): Foo = this.copy(prop1 = propA)
def withPropB(:propB): Foo = this.copy(prop2 = propB)
def withPropC(:propC): Foo = this.copy(prop3 = propC)
}
上面的代码将仅应用最终的this.withPropC
调用,因此仅prop3被更新。
但是,如果我执行以下操作
case class Foo(prop1: prop, prop2: prop2, prop3:prop3) extends FooParent {
override def fooMethod(){
val propA = gen()
val propB = gen()
val propC = gen()
// here
val one = this.withPropA(propA)
val two = one.withPropB(propB)
two.withPropC(propC)
}
def withPropA(:propA): Foo = this.copy(prop1 = propA)
def withPropB(:propB): Foo = this.copy(prop2 = propB)
def withPropC(:propC): Foo = this.copy(prop3 = propC)
}
然后所有属性都会更新。为什么会这样?
Case类是不可变的,因此基于copy
的函数(例如那些withProp*
)永远不会使this
突变。
此外,在顺序更改属性的情况下,每次更新都必须应用于前一个(链)的结果;不在[原始] this
上,它将创建与每个不相关的更新相对应的单独实例。
如果您确实打算使用此类功能,则应该使用
withPropA(propA). // chain update withPropB(propB). // chain withPropC(propC)
可以写的内容:
copy(prop1 = propA, prop2 = propB, prop3 = propC)