Pattern matching can also be used to check the type of an instance, rather than using isInstanceOf[B]
:
val anyRef: AnyRef = ""
anyRef match {
case _: Number => "It is a number"
case _: String => "It is a string"
case _: CharSequence => "It is a char sequence"
}
//> res0: String = It is a string
The order of the cases is important:
anyRef match {
case _: Number => "It is a number"
case _: CharSequence => "It is a char sequence"
case _: String => "It is a string"
}
//> res1: String = It is a char sequence
In this manner it is similar to a classical 'switch' statement, without the fall-through functionality. However, you can also pattern match and 'extract' values from the type in question. For instance:
case class Foo(s: String)
case class Bar(s: String)
case class Woo(s: String, i: Int)
def matcher(g: Any):String = {
g match {
case Bar(s) => s + " is classy!"
case Foo(_) => "Someone is wicked smart!"
case Woo(s, _) => s + " is adventerous!"
case _ => "What are we talking about?"
}
}
print(matcher(Foo("Diana"))) // prints 'Diana is classy!'
print(matcher(Bar("Hadas"))) // prints 'Someone is wicked smart!'
print(matcher(Woo("Beth", 27))) // prints 'Beth is adventerous!'
print(matcher(Option("Katie"))) // prints 'What are we talking about?'
Note that in the Foo
and Woo
case we use the underscore (_
) to 'match an unbound variable'. That is to say that the value (in this case Hadas
and 27
, respectively) is not bound to a name and thus is not available in the handler for that case. This is useful shorthand in order to match 'any' value without worrying about what that value is.