当前位置: 首页 > 文档资料 > Scala 中文文档 >

模式匹配( Pattern Matching)

优质
小牛编辑
131浏览
2023-12-01

在函数值和闭包之后,模式匹配是Scala中使用次数最多的第二个特性。 Scala在处理消息时为模式匹配提供了很好的支持。

模式匹配包括一系列备选方案,每个备选方案都以关键字case开头。 每个替代方案都包括一个pattern和一个或多个expressions ,如果模式匹配,将对其进行评估。 箭头符号=“将模式与表达式分开。

请尝试以下示例程序,该程序显示如何匹配整数值。

例子 (Example)

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"
   }
}

将上述程序保存在Demo.scala 。 以下命令用于编译和执行此程序。

Command

\>scalac Demo.scala
\>scala Demo

输出 (Output)

many

带有case语句的块定义了一个函数,它将整数映射到字符串。 match关键字提供了一种将函数(如上面的模式匹配函数)应用于对象的便捷方法。

尝试以下示例程序,该程序将值与不同类型的模式进行匹配。

例子 (Example)

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"
   }
}

将上述程序保存在Demo.scala 。 以下命令用于编译和执行此程序。

Command

\>scalac Demo.scala
\>scala Demo

输出 (Output)

2
many
one

使用Case Classes进行匹配

case classes是特殊类,用于与案例表达式进行模式匹配。 从语法上讲,这些是带有特殊修饰符的标准类: case

尝试以下,它是一个使用case类的简单模式匹配示例。

例子 (Example)

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)
}

将上述程序保存在Demo.scala 。 以下命令用于编译和执行此程序。

Command

\>scalac Demo.scala
\>scala Demo

输出 (Output)

Hi Alice!
Hi Bob!
Age: 32 year, name: Charlie?

添加case关键字会使编译器自动添加许多有用的功能。 关键字建议在模式匹配中与案例表达式关联。

首先,编译器自动将构造函数参数转换为不可变字段(vals)。 val关键字是可选的。 如果需要可变字段,请使用var关键字。 因此,我们的构造函数参数列表现在更短。

其次,编译器自动为类生成equals, hashCode,toString方法,该方法使用指定为构造函数参数的字段。 因此,我们不再需要自己的toString()方法。

最后, Person类的主体也变空了,因为没有我们需要定义的方法!