Case classes are how Scala models data: records, messages, events, DTOs.
Prefix a class with case and the compiler generates the boilerplate for an immutable data type:
- constructor parameters are public
vals; equalsandhashCodecompare by structure (field values), so twoPoint(1, 2)are equal;- a readable
toString:Point(1,2); - a
copymethod for making modified copies:p.copy(y = 5); - a companion
applyandunapply, enabling construction withoutnewand pattern matching on the fields.
Case classes are the default way to represent data. Since they're immutable, "updating" means copy, which is cheap because unchanged fields are shared. They work naturally as Map keys and Set elements thanks to structural equality.
Case objects are the singleton version, useful as constant members of a closed hierarchy. A case class with no parameters must still have an empty list: case class Tick().
Case classes are also Products: productArity and productElementNames give generic access to fields, which serialisation and derivation libraries build on. Avoid inheriting from a case class; model variations with a sealed trait or enum instead (next lessons).
Example
case class Point(x: Int, y: Int):
def +(o: Point): Point = Point(x + o.x, y + o.y)
case class User(name: String, email: String, active: Boolean = true)
val p = Point(1, 2)
val q = Point(1, 2)
println(p == q) // true (structural)
println(p eq q) // false (different objects)
println(p + Point(10, 10)) // Point(11,12)
val u = User("ana", "ana@example.com")
val inactive = u.copy(active = false)
println(inactive) // User(ana,ana@example.com,false)
val seen = Set(p, q, Point(0, 0))
println(seen.size) // 2
p match
case Point(0, y) => println(s"on the y axis at $y")
case Point(x, y) => println(s"at $x, $y") // at 1, 2
println(u.productElementNames.toList) // List(name, email, active)Remember
case class= immutable fields + structural equality + copy + pattern matching- Update by
copy(field = value) - Safe as Map keys and Set elements
- Model variants with sealed traits or enums, not case-class inheritance
Watch out for
- Putting
varfields in a case class used as a Map key; mutating it breaks hashing.