Scala pattern matching


Scala provides a powerful pattern matching mechanism and is widely used.

A pattern match consists of a sequence of alternatives, each starting with the keyword case. Each alternative contains a pattern and one or more expressions. The arrow symbol => separates the pattern and expression.

The following is a simple integer value pattern matching example:

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, the output result is:

$ scalac Test.scala 
$ scala Test
many

match corresponds to the switch in Java, but is written in after the selector expression. That is: Selector match {alternative}.

The match expression is calculated by trying each pattern in the order in which the code is written. As long as a matching case is found, the remaining cases will not continue to match.

Next let’s look at a pattern matching of 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, the output result is:

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

The first case in the instance corresponds to the integer type Value 1, the second case corresponds to the string value two, the second case corresponds to the string value two, and the third case corresponds to the type pattern, which is used to determine whether the incoming value is an integer. Compared with using isInstanceOf to determine the type , using pattern matching is better. The fourth case represents the default full match alternative, that is, the match when no other match is found, similar to default in switch.


Using sample classes

The class definition using the case keyword is the case class. The case class is a special class that has been optimized to use for pattern matching.

The following is a simple example of the 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 + "?")
         }
      }
   }
   // 样例类
   case class Person(name: String, age: Int)
}

Execute the above code, the output result is:

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

When declaring the sample class, the following process occurs automatically :

  • Each parameter of the constructor becomes a val unless explicitly declared as var, but this is not recommended;

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

  • The unapply method is provided so that pattern matching can work;

  • Generate toString, equals, hashCode and copy methods unless the definition of these methods is given explicitly.