scalabeginner

Case Classes and Objects

Define immutable data with case classes: copy, equality, destructuring, and companion objects.

scala
// Case classes: immutable data containers
case class User(
  id: Long,
  name: String,
  email: String,
  active: Boolean = true
)

case class Address(
  street: String,
  city: String,
  zip: String,
  country: String = "US"
)

case class UserProfile(user: User, address: Address)

// Companion object with factory methods
object User:
  def fromEmail(email: String): User =
    val name = email.takeWhile(_ != '@')
    User(0, name, email)

@main def run(): Unit =
  val alice = User(1, "Alice", "alice@test.com")
  val bob = User(2, "Bob", "bob@test.com")

  // Structural equality (not reference)
  val alice2 = User(1, "Alice", "alice@test.com")
  println(s"Equal: ${alice == alice2}")  // true

  // Copy with modifications
  val inactive = alice.copy(active = false)
  println(s"Inactive: $inactive")

  // Destructuring
  val User(id, name, email, _) = alice
  println(s"id=$id, name=$name, email=$email")

  // Pattern matching on case class
  alice match
    case User(_, n, e, true) => println(s"Active user: $n ($e)")
    case User(_, n, _, false) => println(s"Inactive: $n")

  // Factory method
  val fromEmail = User.fromEmail("carol@example.com")
  println(s"From email: $fromEmail")

  // toString is auto-generated
  println(alice)

  // Nested case classes
  val profile = UserProfile(
    alice,
    Address("123 Main St", "NYC", "10001")
  )
  println(s"Profile: $profile")

  // Update nested with copy
  val moved = profile.copy(
    address = profile.address.copy(city = "LA", zip = "90001")
  )

Use Cases

  • Domain modeling with immutable data
  • Data transfer objects
  • Safe data updates with copy

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.