Case Classes and Pattern Matching
Copy and Update
Make a changed copy without mutating the original.
copy-update
The generated `copy` method returns a new case class instance with selected fields replaced. The original stays unchanged, which keeps state immutable.
Copy and Update
CopyUpdate.scala
Replay: real traced execution (multi-file project)
case class Account(owner: String, balance: Int)
object Main {
def main(args: Array[String]): Unit = {
val deposit = 50
val base = Account("Ann", 100)
val balance = base.balance + deposit
val updated = base.copy(balance = balance)
println("owner=" + updated.owner)
println("oldBalance=" + base.balance)
println("newBalance=" + updated.balance)
}
}
case class Account(owner: String, balance: Int)
object Main {
def main(args: Array[String]): Unit = {
val deposit = 10
val base = Account("Ann", 100)
val balance = base.balance + deposit
val updated = base.copy(balance = balance)
println("owner=" + updated.owner)
println("oldBalance=" + base.balance)
println("newBalance=" + updated.balance)
}
}
case class Account(owner: String, balance: Int)
object Main {
def main(args: Array[String]): Unit = {
val deposit = 200
val base = Account("Ann", 100)
val balance = base.balance + deposit
val updated = base.copy(balance = balance)
println("owner=" + updated.owner)
println("oldBalance=" + base.balance)
println("newBalance=" + updated.balance)
}
}
deposit ← 50, base ← Account(Ann,100), balance ← 150, updated ← Account(Ann,150)
3object Main {4 def main(args: Array[String]): Unit = {5 val deposit→ 50 = 50 //@deposit=10, 2006 val base→ Account(Ann,100) = Account("Ann", 100)7 val balance→ 150 = baseAccount(Ann,100).balance + deposit508 val updated→ Account(Ann,150) = baseAccount(Ann,100).copy(balance→ 150 = balance)910 println("owner=" + updated.ownerAnn)11 println("oldBalance=" + base.balance100)12 println("newBalance=" + updated.balance150)13 }14}outputowner=Ann oldBalance=100 newBalance=150
deposit ← 10, base ← Account(Ann,100), balance ← 110, updated ← Account(Ann,110)
3object Main {4 def main(args: Array[String]): Unit = {5 val deposit→ 10 = 106 val base→ Account(Ann,100) = Account("Ann", 100)7 val balance→ 110 = baseAccount(Ann,100).balance + deposit108 val updated→ Account(Ann,110) = baseAccount(Ann,100).copy(balance→ 110 = balance)910 println("owner=" + updated.ownerAnn)11 println("oldBalance=" + base.balance100)12 println("newBalance=" + updated.balance110)13 }14}outputowner=Ann oldBalance=100 newBalance=110
deposit ← 200, base ← Account(Ann,100), balance ← 300, updated ← Account(Ann,300)
3object Main {4 def main(args: Array[String]): Unit = {5 val deposit→ 200 = 2006 val base→ Account(Ann,100) = Account("Ann", 100)7 val balance→ 300 = baseAccount(Ann,100).balance + deposit2008 val updated→ Account(Ann,300) = baseAccount(Ann,100).copy(balance→ 300 = balance)910 println("owner=" + updated.ownerAnn)11 println("oldBalance=" + base.balance100)12 println("newBalance=" + updated.balance300)13 }14}outputowner=Ann oldBalance=100 newBalance=300
Follow the Copy
depositstarts at50.baseisAccount("Ann", 100).balanceadds the deposit:100 + 50 = 150.base.copy(balance = balance)makesupdatedwith the new balance.- The original
base.balancestill prints as100. | deposit | old balance | new balance | owner | | ---: | ---: | ---: | --- | | 10 | 100 | 110 | Ann | | 50 | 100 | 150 | Ann | | 200 | 100 | 300 | Ann |
Exercise: CopyUpdate.scala
Reproduce owner=Ann, oldBalance=100, and newBalance=150, then use deposits 10 and 200 to predict newBalance=110 and newBalance=300.