How to use a Scala match expression instead of isInstanceOf (to match types)

This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 3.14, “How to use a match expression instead of isInstanceOf (to match types).”

Problem

In Scala, you want to write a block of code to match one type, or multiple different types.

Solution

You can use the isInstanceOf method to test the type of an object:

if (x.isInstanceOf[Foo]) { do something ...

However, some programmers discourage this approach, and in other cases, it may not be convenient. In these instances, you can handle the different expected types in a match expression.

For example, you may be given an object of unknown type, and want to determine if the object is an instance of a Person:

def isPerson(x: Any): Boolean = x match {
    case p: Person => true
    case _ => false
}

Or you may be given an object that extends a known supertype, and then want to take different actions based on the exact subtype. In the following example, the printInfo method is given a SentientBeing, and then handles the subtypes differently:

trait SentientBeing
trait Animal extends SentientBeing
case class Dog(name: String) extends Animal
case class Person(name: String, age: Int) extends SentientBeing

// later in the code ...
def printInfo(x: SentientBeing) = x match {
    case Person(name, age) => // handle the Person
    case Dog(name) => // handle the Dog
}

Discussion

As shown, a match expression lets you match multiple types, so using it to replace the isInstanceOf method is just a natural use of the case syntax and the general pattern-matching approach used in Scala applications.

In simple examples, the isInstanceOf method can be a simpler approach to determining whether an object matches a type:

if (o.isInstanceOf[Person]) { // handle this ...

However, with more complex needs, a match expression is more readable than an if/else statement.

I hope this has been helpful. All the best, Al.