Класс Case неизменный, все еще может изменять значения параметров - PullRequest
3 голосов
/ 15 июня 2019

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

нижеуказанный класс case может быть изменен, поэтому мой вопрос: как это возможно, поскольку классы case являются неизменяемыми, но в этой конструкции я могу изменить параметры класса case?

case class RegisterCustomerRequest(`first-name`: String,
                                   `last-name`: String,
                                   `house-details`: String,
                                   street: String,
                                   zipcode: String,
                                   city: String

    extends WcRequestData {

    def this(cardHolderData: CardHolderData,
           registrationCode: RegistrationCode,
           customerNumber: Long,
           cardDesignImageId: String) =
    this(`first-name` = cardHolderData.firstname,
         `last-name` = cardHolderData.lastname,
          street = cardHolderData.streetAndNumber,
          zipcode = cardHolderData.zipCode,
          city = cardHolderData.city,


       #   `house-details` = 
          s"${if (cardHolderData.employerName.contains("&")) 
          cardHolderData.employerName.replace("&" , " & ") else " / 
           "}${cardHolderData.employerName} ")#
    }

почему я могуопределить метод def this, который может изменять значения параметров.Для чего эта конструкция хороша для этого хорошего стиля кодирования?

1 Ответ

1 голос
/ 15 июня 2019

Класс case RegisterCustomerRequest по-прежнему неизменен, однако он имеет вспомогательный конструктор def this, который позволяет создавать его другим способом.Например, учитывая

case class User(name: String)

case class Foo(name: String) {
  def this(user: User) {
    this(name = user.name)
  }
}

, мы можем построить Foo примерно так

Foo("picard")

или используя вспомогательный конструктор

new Foo(User("picard"))

В обоих случаях результатнеизменный объект.Чтобы подтвердить неизменность, попробуйте переназначить name после построения

(new Foo(User("picard"))).name = "worf" // Error: reassignment to val 

. Как подсказывает som-snytt, мы можем определить apply метод для объекта-компаньона вместо вспомогательного конструктора, например,

object Foo {
  def apply(user: User): Foo = Foo(user.name)
}

который позволяет следующую конструкцию

Foo(User("picard"))
...