案例类和不可变性

默认情况下,Scala 编译器使用 val 为参数列表中的每个参数添加前缀。这意味着,默认情况下,case 类是不可变的。每个参数都有一个访问器方法,但没有 mutator 方法。例如:

case class Foo(i: Int)

val fooInstance = Foo(1)
val j = fooInstance.i       // get
fooInstance.i = 2           // compile-time exception (mutation: reassignment to val)

将 case 类中的参数声明为 var 会覆盖默认行为并使 case 类可变:

case class Bar(var i: Int)

val barInstance = Bar(1)
val j = barInstance.i       // get
barInstance.i = 2           // set

案例类是可变的的另一个例子是 case 类中的值是可变的:

import scala.collection._

case class Bar(m: mutable.Map[Int, Int])

val barInstance = Bar(mutable.Map(1 -> 2))
barInstance.m.update(1, 3)                  // mutate m
barInstance                                 // Bar(Map(1 -> 3)

请注意,此处发生的突变位于 m 指向的地图中,而不是 m 本身。因此,如果其他一些对象有 m 作为成员,它也会看到变化。注意在下面的示例中如何更改 instanceA 也会改变 instanceB

import scala.collection.mutable

case class Bar(m: mutable.Map[Int, Int])

val m = mutable.Map(1 ->2)
val barInstanceA = Bar(m)
val barInstanceB = Bar(m)
barInstanceA.m.update(1,3)
barInstanceA  // Bar = Bar(Map(1 -> 3))
barInstanceB  // Bar = Bar(Map(1 -> 3))
m  // scala.collection.mutable.Map[Int,Int] = Map(1 -> 3)