案例類和不可變性

預設情況下,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)