Scala Pattern Matching
Scala Pattern Matching
Section titled “Scala Pattern Matching”Pattern matching is one of Scala’s most powerful and frequently used features. It allows you to check a value against a series of patterns and execute corresponding code blocks, simplifying complex conditional logic, especially when dealing with structured data.
A pattern match expression starts with a value followed by the match keyword and a block containing case clauses. Each case defines a pattern and an expression (=> expression) to execute if the value matches the pattern. The first matching pattern’s expression is evaluated.
Basic Matching:
Section titled “Basic Matching:”Here’s a simple example matching an integer:
@main def PatternMatchDemo(): Unit = {
def describe(x: Int): String = x match { case 1 => "one" case 2 => "two" case n if n > 2 && n < 10 => s"a small number ($n)" // Pattern guard case _ => "something else" // Wildcard pattern }
println(describe(1)) println(describe(5)) println(describe(100))}Output:
onea small number (5)something elseKey elements in the example:
case 1 => ...: Matches the literal value 1.case n if n > 2 ...: Matches any integer, binds it ton, and applies a guard condition (if).case _ => ...: The wildcard_matches anything not caught by previous cases. It’s crucial for exhaustiveness.
Matching on Types:
Section titled “Matching on Types:”You can also match based on the type of the value, especially useful with Any:
@main def TypeMatchDemo(): Unit = {
def matchType(x: Any): String = x match { case i: Int => s"It's an Integer: $i" case s: String => s"It's a String: $s" case d: Double => s"It's a Double: $d" case _: List[_] => "It's a List of something" case _ => "It's something else" }
println(matchType(42)) println(matchType("Hello Scala")) println(matchType(3.14)) println(matchType(List(1, 2, 3))) println(matchType(true))}Output:
It's an Integer: 42It's a String: Hello ScalaIt's a Double: 3.14It's a List of somethingIt's something elseThe pattern s: String checks if x is a String and, if so, binds it to the variable s of type String.
Matching using Case Classes:
Section titled “Matching using Case Classes:”Case classes are specifically designed to work seamlessly with pattern matching. They automatically provide companion objects with apply and unapply methods, making construction and deconstruction easy.
// Define a case classcase class Person(name: String, age: Int)
@main def CaseClassMatchDemo(): Unit = { val alice = Person("Alice", 30) val bob = Person("Bob", 25) val charlie = Person("Charlie", 30)
for (person <- List(alice, bob, charlie)) { person match { case Person("Alice", 30) => println(s"Hi Alice!") case Person("Bob", age) => println(s"Hi Bob! You are $age years old.") case Person(name, 30) => println(s"Hi $name! You are 30.") case Person(name, age) => println(s"Who are you, $name of age $age?") } }}Output:
Hi Alice!Hi Bob! You are 25 years old.Hi Charlie! You are 30.Benefits of case class:
- Immutable fields by default (constructor arguments become
valfields). - Automatic implementation of
equals,hashCode, andtoStringbased on constructor arguments. - Automatic
applymethod (e.g.,Person("Alice", 30)instead ofnew Person(...)). - Automatic
unapplymethod, enabling easy deconstruction in pattern matching (e.g.,case Person(name, age) => ...).
Practical Application:
Section titled “Practical Application:”Pattern matching is used extensively in Scala for tasks like: processing messages in actor systems (like Akka), handling optional values (Option), processing results (Try or Either), deconstructing complex data structures (like JSON or XML trees), and implementing state machines.
Further Learning:
Section titled “Further Learning:”Explore matching on collections (like List(1, 2, _*)), Option (Some(v) vs None), and using extractors (unapply methods) for custom pattern matching logic. Check the official Scala documentation for more advanced patterns.