Scala 模式匹配

  • 模式匹配

    在函数值和闭包之后,模式匹配是Scala的第二广泛使用的功能。Scala在处理消息时为模式匹配提供了强大的支持。模式匹配包括一系列备选方案,每种备选方案均以关键字case开头。每个备选方案都包含一个模式和一个或多个表达式,如果模式匹配则将对其进行计算。箭头符号=>将模式与表达式分开。请尝试下面的示例程序,该程序显示了如何与整数值匹配。
    
    object Demo {
       def main(args: Array[String]) = {
          println(matchTest(3))
       }
       
       def matchTest(x: Int): String = x match {
          case 1 => "one"
          case 2 => "two"
          case _ => "many"
       }
    }
    
    尝试一下
    输出-
    
    many
    
    case语句的块定义一个函数,该函数将整数映射到字符串。match关键字提供了一种将函数(如上面的模式匹配函数)应用于对象的便捷方法。请尝试以下示例程序,该程序将值与不同类型的模式匹配。
    
    object Demo {
       def main(args: Array[String]) = {
          println(matchTest("two"))
          println(matchTest("test"))
          println(matchTest(1))
       }
       
       def matchTest(x: Any): Any = x match {
          case 1 => "one"
          case "two" => 2
          case y: Int => "scala.Int"
          case _ => "many"
       }
    }
    
    尝试一下
    输出-
    
    2
    many
    one
    
  • 使用case类进行匹配

    case类是用于与case表达式进行模式匹配的特殊类。从语法上讲,这些是带有特殊修饰符的标准类:case。试试下面的例子,这是一个使用case类的简单模式匹配示例。
    
    object Demo {
       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)
    }
    
    尝试一下
    输出-
    
    Hi Alice!
    Hi Bob!
    Age: 32 year, name: Charlie?
    
    添加case关键字会导致编译器自动添加许多有用的特性。case关键字表示在模式匹配中与大小写表达式的关联。首先,编译器自动将构造函数参数转换为不可变字段(vals)。val关键字是可选的。如果需要可变字段,请使用var关键字。因此,我们的构造函数参数列表现在更短了。其次,编译器自动为类实现equalshashCodetoString方法,这些方法使用指定为构造函数参数的字段。因此,我们不再需要自己的toString()方法。最后,Person类的主体变成空的,因为没有需要定义的方法!