scala - 不可变的案例类仍然能够更改参数值

标签 scala immutability case-class constructor-overloading

我查看了一位同事的一些代码,发现了一个默认情况下不可变的案例类。

下面的案例类可以更改,所以我的问题是这怎么可能,因为案例类是不可变的,但在这个构造中我可以更改案例类参数?

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方法。这种构造有什么用?这种好的编码风格?

最佳答案

案例类 RegisterCustomerRequest 仍然是不可变的,但是它有一个 auxiliary constructor 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"))

在这两种情况下,结果都是一个不可变对象(immutable对象)。要确认不变性,请尝试在构造后重新分配 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"))

关于scala - 不可变的案例类仍然能够更改参数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56613999/

相关文章:

scala - Spark 将 sql 窗口函数迁移到 RDD 以获得更好的性能

java - Java 8 中是否有等效于 Scala 的 Either?

language-agnostic - 函数式编程 : immutability etc

oop - 对于 OOP,不可变和不变是同义词吗?

java - 将单例用于不可变的无参数类不好吗?

scala - 案例类是否允许使用构造函数?

斯卡拉 SortedMap : Get all keys greater than a given key

scala - 结构化流异常 : Append output mode not supported for streaming aggregations

scala - 在 twitter chill 中处理案例类(Scala 接口(interface)到 Kryo)?

scala - 案例类构造函数似乎是虚假的 "does not take arguments"错误