案例類和不可變性
預設情況下,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)