How to use case classes in Scala match expressions

This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 3.12, “How to use case classes in Scala match expressions.”

Problem

You want to match different case classes (or case objects) in a Scala match expression, such as when receiving messages in an actor.

Solution

Use the different patterns shown in the previous recipe to match case classes and objects, depending on your needs.

The following example demonstrates how to use patterns to match case classes and case objects in different ways, depending primarily on what information you need on the right side of each case statement. In this example, the Dog and Cat case classes and the Woodpecker case object are different subtypes of the Animal trait:

sealed trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
case object Woodpecker extends Animal

object CaseClassTest extends App {
    def determineType(x: Animal): String = x match {
        case Dog(moniker) => "Got a Dog, name = " + moniker
        case _: Cat => "Got a Cat (ignoring the name)"
        case Woodpecker => "That was a Woodpecker"
        case _ => "That was something else"
    }
    println(determineType(new Dog("Rocky")))
    println(determineType(new Cat("Rusty the Cat")))
    println(determineType(Woodpecker))
}

When the code is compiled and run, the output is:

Got a Dog, name = Rocky
Got a Cat (ignoring the name)
That was a Woodpecker

In this example, if the Dog class is matched, its name is extracted and used in the print statement on the right side of the expression. To show that the variable name used when extracting the name can be any legal variable name, I use the name moniker.

When matching a Cat, I want to ignore the name, so I use the syntax shown to match any Cat instance. Because Woodpecker is defined as a case object and has no name, it is also matched as shown.