Scala - использование ключевого слова this несколько раз одно за другим завершится неудачей - PullRequest
0 голосов
/ 05 ноября 2019

Я столкнулся с проблемой, когда использование ключевого слова this в Scala несколько раз в одном и том же методе на самом деле не будет выполнено.

Я не могу воспроизвести проблему здесь, потому что кодовая база слишком велика, но я сделаю все возможное, чтобы показать проблему.

У меня есть класс 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)

}

, все свойства будут обновлены. Почему это?

1 Ответ

3 голосов
/ 05 ноября 2019

Класс Case является неизменяемым, поэтому функции copy (например, withProp*) никогда не изменяются this.

Более того, в случае последовательных изменений свойств каждое обновление должно применяться к результату. предыдущего (цепочка);Не включено (оригинально) this, что создаст отдельные экземпляры, соответствующие каждому несвязанному обновлению.

Если вы действительно намереваетесь использовать такие функции, это должно быть

withPropA(propA). // chain update
  withPropB(propB). // chain
  withPropC(propC)

Что может бытьнаписано:

copy(prop1 = propA, prop2 = propB, prop3 = propC)
...