Scala - 使用变量和自定义类型的模式匹配
模式匹配是 Scala 中第二常用的特性,仅次于函数值和闭包。Scala 为模式匹配提供了强大的支持,用于处理消息。模式匹配的一个方面是在模式中使用变量。它可以绑定到值,从而编写更具表达力的代码。
模式匹配包含一系列备选方案,每个备选方案以关键字 case 开头。每个备选方案包含一个 pattern 和一个或多个 expressions,如果模式匹配成功,这些表达式将被求值。箭头符号 => 将模式与表达式分隔开。
变量的模式匹配
模式匹配可用于将字符串和变量与模式进行测试。这些操作会根据匹配结果返回不同的结果。匹配字符串和变量的语法如下 -
def typedPatternMatching(any: Any): String = {
any match {
case string: String => s"I am a string. My value: $string"
case integer: Int => s"I am an integer. My value: $integer"
case _ => s"I am from an unknown type. My value: $any"
}
}
此函数接受类型为 Any 的参数,并将其与不同类型进行匹配。它返回一个描述匹配类型及其值的字符串。
示例
def typedPatternMatching(any: Any): String = {
any match {
case string: String => s"I am a string. My value: $string"
case integer: Int => s"I am an integer. My value: $integer"
case _ => s"I am from an unknown type. My value: $any"
}
}
object Demo {
def main(args: Array[String]): Unit = {
val mixedList: List[Any] = List(42, "Scala", 3.14)
mixedList.foreach { element =>
println(typedPatternMatching(element))
}
}
}
将上述程序保存为 Demo.scala。使用以下命令编译并执行此程序。
命令
> scalac Demo.scala > scala Demo
输出
I am an integer. My value: 42 I am a string. My value: Scala I am from an unknown type. My value: 3.14
我们将 mixedList 中的每个元素传递给 typedPatternMatching 函数。它将元素与不同类型进行匹配并打印结果。
模式匹配中的稳定标识符
在某些情况下,您可能希望与存储在变量中的特定值进行匹配。但是,在模式中使用变量名会将变量绑定到匹配的值,而不是与存储的值进行比较。您可以使用稳定标识符来获得所需的行为。稳定标识符必须以大写字母开头,或用反引号包围。
示例
def mMatch(s: String) = {
val target: String = "a"
s match {
case `target` => println(s"It was $target")
case _ => println("It was something else")
}
}
def mMatch2(s: String) = {
val Target: String = "a"
s match {
case Target => println(s"It was $Target")
case _ => println("It was something else")
}
}
在这里,为模式中的变量名以大写字母开头,可以匹配变量中存储的特定值。
模式匹配中的变量绑定
当一个模式匹配一个值时,模式中的变量会绑定到该值的相应部分。
示例
以下示例展示了如何在模式匹配中使用变量绑定 –
object Demo {
def main(args: Array[String]): Unit = {
val maybeValue: Option[Int] = Some(42)
maybeValue match {
case Some(value) => println(s"Value is: $value")
case None => println("No value")
}
}
}
将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。
命令
> scalac Demo.scala > scala Demo
输出
Value is: 42
在这里,maybeValue 变量与 Option 类型的 Some 和 None 情况进行匹配,value 变量绑定到包含的整数。
与自定义类型一起使用模式匹配
您可以将模式匹配扩展到自定义类型和类。这样,您可以分解实例并直接访问其字段。
示例
以下示例展示了如何与自定义类型一起使用模式匹配 -
sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(width: Double, height: Double) extends Shape
object Demo {
def main(args: Array[String]): Unit = {
val shape: Shape = Circle(5.0)
shape match {
case Circle(r) => println(s"Circle with radius: $r")
case Rectangle(w, h) => println(s"Rectangle with width: $w and height: $h")
case _ => println("Unknown shape")
}
}
}
将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。
命令
> scalac Demo.scala > scala Demo
输出
Circle with radius: 5.0
在这个示例中,shape 变量与不同的 case class 进行匹配。变量 r、w 和 h 分别绑定到 Circle 和 Rectangle 的相应字段。
模式匹配与变量总结
- 模式匹配用于测试值并使用模式将其分解为组成部分。
- 您可以将稳定的标识符与变量中存储的特定值进行匹配。
- 模式中的变量绑定用于提取并处理匹配值的部分。
- 您可以使用自定义类型的模式匹配来访问字段并分解实例。
- 类型化模式匹配简化了类型处理并提高了代码可读性。