English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Scala Pattern Matching

Scala provides a powerful pattern matching mechanism, which is also very widely used.

A pattern match contains a series of options, each starting with the keyword case. Each option contains a pattern and one or more expressions. The arrow symbol => separates the pattern and the expression.

Here is a simple example of pattern matching with integer values:

object Test {
   def main(args: Array[String]) {
      println(matchTest(3))
   }
   def matchTest(x: Int): String = x match {
      case 1 => "one"
      case 2 => "two"
      case _ => "many"
   }
}

Execute the above code, and the output will be:

$ scalac Test.scala 
$ scala Test
many

Match corresponds to Java's switch, but written after the selector expression. That is: Selector match {options}.

The match expression completes the calculation by trying each pattern in the order of code writing, and once a matching case is found, the remaining cases will not continue to match.

Next, let's look at a pattern matching with different data types:

object Test {
   def main(args: Array[String]) {
      println(matchTest("two"))
      println(matchTest("test"))
      println(matchTest(1))
      println(matchTest(6))
   }
   def matchTest(x: Any): Any = x match {
      case 1 => "one"
      case "two" => 2
      case y: Int => "scala.Int"
      case _ => "many"
   }
}

Execute the above code, and the output will be:

$ scalac Test.scala 
$ scala Test
2
many
one
scala.Int

The first case in the example corresponds to an integer value 1, the second case corresponds to the string value "two", the third case corresponds to a type pattern used to determine if the input value is an integer, which is better than using isInstanceOf to determine the type. The fourth case represents the default wildcard option, which is the match item when no other matches are found, similar to the default in switch.

Using sample classes

A class definition that uses the case keyword is a sample class (case classes), which is a special type of class that is optimized for pattern matching.

Here is a simple example of a sample class:

object Test {
   def main(args: Array[String]) {
        val alice = new Person("Alice", 25)
        val bob = new Person("Bob", 32)
        val charlie = new Person("Charlie", 32)
   
    for (person <- List(alice, bob, charlie)) {
        person match {
            case Person("Alice", 25) => println("Hi Alice!")
            case Person("Bob", 32) => println("Hi Bob!")
            case Person(name, age) =>
               println("Age: " + age + " year, name: " + name + "?"
         }
      }
   }
   // Example Class
   case class Person(name: String, age: Int)
}

Execute the above code, and the output will be:

$ scalac Test.scala 
$ scala Test
Hi Alice!
Hi Bob!
Age: 32 year, name: Charlie?

The following process automatically occurs when declaring an example class:

  • Each constructor parameter becomes a val unless explicitly declared as var, but it is not recommended to do so;

  • An apply method is provided in the companion object, so objects can be constructed without using the new keyword;

  • Provide an unapply method to make pattern matching work;

  • Generate toString, equals, hashCode, and copy methods unless these method definitions are explicitly given.