模式匹配 #
一、match 表达式 #
1.1 基本语法 #
scala
val result = value match
case pattern1 => result1
case pattern2 => result2
case _ => defaultResult
1.2 简单示例 #
scala
val day = 1
val dayName = day match
case 1 => "Monday"
case 2 => "Tuesday"
case 3 => "Wednesday"
case 4 => "Thursday"
case 5 => "Friday"
case 6 => "Saturday"
case 7 => "Sunday"
case _ => "Unknown"
1.3 match 是表达式 #
match 有返回值:
scala
val grade = score match
case s if s >= 90 => "A"
case s if s >= 80 => "B"
case s if s >= 70 => "C"
case s if s >= 60 => "D"
case _ => "F"
二、常量模式 #
2.1 匹配常量 #
scala
def describe(x: Any): String = x match
case 0 => "zero"
case 1 => "one"
case true => "true"
case false => "false"
case "hello" => "a greeting"
case _ => "something else"
2.2 匹配 Nil #
scala
val result = list match
case Nil => "empty"
case _ => "non-empty"
三、变量模式 #
3.1 绑定变量 #
scala
val result = x match
case 0 => "zero"
case n => s"non-zero: $n"
3.2 使用 @ 绑定 #
scala
val result = list match
case head :: tail => s"head: $head, rest: $tail"
case empty @ Nil => s"empty list: $empty"
四、类型模式 #
4.1 匹配类型 #
scala
def describe(x: Any): String = x match
case i: Int => s"Int: $i"
case s: String => s"String: $s"
case d: Double => s"Double: $d"
case b: Boolean => s"Boolean: $b"
case list: List[?] => s"List with ${list.length} elements"
case _ => "Unknown type"
4.2 泛型类型匹配 #
scala
def process(x: Any): String = x match
case list: List[Int] => "List of Int"
case list: List[String] => "List of String"
case _ => "Other"
注意:由于类型擦除,泛型类型匹配有限制。
4.3 数组类型匹配 #
scala
def describe(arr: Array[?]): String = arr match
case a: Array[Int] => "Array of Int"
case a: Array[String] => "Array of String"
case a: Array[Double] => "Array of Double"
case _ => "Other array"
五、模式守卫 #
5.1 使用 if 条件 #
scala
val result = x match
case n if n > 0 => "positive"
case n if n < 0 => "negative"
case _ => "zero"
5.2 复杂条件 #
scala
val category = age match
case a if a < 0 => "invalid"
case a if a < 13 => "child"
case a if a < 20 => "teenager"
case a if a < 65 => "adult"
case _ => "senior"
5.3 多条件守卫 #
scala
val result = (x, y) match
case (a, b) if a > 0 && b > 0 => "both positive"
case (a, b) if a < 0 && b < 0 => "both negative"
case _ => "mixed"
六、集合模式 #
6.1 List 模式 #
scala
val result = list match
case Nil => "empty"
case head :: Nil => s"single element: $head"
case head :: second :: Nil => s"two elements: $head, $second"
case head :: tail => s"head: $head, tail length: ${tail.length}"
6.2 List 特定元素 #
scala
val result = list match
case List(1, 2, 3) => "1, 2, 3"
case List(1, _*) => "starts with 1"
case List(a, b, c) => s"three elements: $a, $b, $c"
case _ => "other"
6.3 Seq 模式 #
scala
val result = seq match
case Seq(1, 2, 3) => "exact match"
case Seq(1, _*) => "starts with 1"
case Seq(a, b, c, _*) => s"at least three: $a, $b, $c"
case _ => "other"
6.4 Tuple 模式 #
scala
val result = tuple match
case (1, 2) => "tuple (1, 2)"
case (x, y) => s"tuple ($x, $y)"
val result2 = (a, b, c) match
case (1, _, 3) => "first is 1, third is 3"
case (x, y, z) => s"($x, $y, $z)"
七、Case Class 模式 #
7.1 匹配 Case Class #
scala
case class Person(name: String, age: Int)
val person = Person("Alice", 25)
val result = person match
case Person("Alice", _) => "It's Alice"
case Person(name, age) if age < 18 => s"$name is a minor"
case Person(name, age) => s"$name is $age years old"
7.2 嵌套模式 #
scala
case class Address(city: String, country: String)
case class Person(name: String, address: Address)
val person = Person("Alice", Address("Beijing", "China"))
val result = person match
case Person(name, Address("Beijing", _)) => s"$name lives in Beijing"
case Person(name, Address(_, "China")) => s"$name lives in China"
case Person(name, _) => s"$name lives somewhere"
7.3 提取器模式 #
scala
case class Point(x: Int, y: Int)
val point = Point(10, 20)
val result = point match
case Point(0, 0) => "origin"
case Point(x, 0) => s"on x-axis at $x"
case Point(0, y) => s"on y-axis at $y"
case Point(x, y) => s"at ($x, $y)"
八、Option 模式 #
8.1 匹配 Option #
scala
val result = opt match
case Some(value) => s"value: $value"
case None => "no value"
8.2 嵌套 Option #
scala
val result = nestedOpt match
case Some(Some(value)) => s"nested value: $value"
case Some(None) => "inner is None"
case None => "outer is None"
8.3 实用示例 #
scala
def getOrElse(opt: Option[String], default: String): String = opt match
case Some(value) => value
case None => default
def mapOption[A, B](opt: Option[A])(f: A => B): Option[B] = opt match
case Some(value) => Some(f(value))
case None => None
九、Either 模式 #
9.1 匹配 Either #
scala
val result = either match
case Right(value) => s"success: $value"
case Left(error) => s"error: $error"
9.2 实用示例 #
scala
def process(result: Either[String, Int]): String = result match
case Right(n) if n > 0 => s"positive: $n"
case Right(n) if n < 0 => s"negative: $n"
case Right(0) => "zero"
case Left(msg) => s"error: $msg"
十、Sealed 类模式 #
10.1 定义 Sealed 类 #
scala
sealed trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
case object Bird extends Animal
10.2 匹配 Sealed 类 #
scala
def describe(animal: Animal): String = animal match
case Dog(name) => s"Dog named $name"
case Cat(name) => s"Cat named $name"
case Bird => "A bird"
编译器会检查是否覆盖所有情况。
十一、提取器 #
11.1 自定义提取器 #
scala
object Even:
def unapply(n: Int): Option[Int] =
if n % 2 == 0 then Some(n / 2) else None
val result = 10 match
case Even(half) => s"Even number, half is $half"
case _ => "Odd number"
11.2 带多个返回值的提取器 #
scala
object Domain:
def unapply(url: String): Option[(String, String)] =
val parts = url.split("\\.")
if parts.length >= 2 then
Some((parts.init.mkString("."), parts.last))
else
None
val result = "www.scala-lang.org" match
case Domain(name, tld) => s"Domain: $name, TLD: $tld"
case _ => "Invalid URL"
11.3 布尔提取器 #
scala
object Positive:
def unapply(n: Int): Boolean = n > 0
val result = x match
case Positive() => "positive"
case _ => "non-positive"
十二、模式匹配最佳实践 #
12.1 使用 Sealed Trait #
scala
sealed trait Result
case class Success(value: Int) extends Result
case class Failure(message: String) extends Result
def handle(result: Result): String = result match
case Success(value) => s"Success: $value"
case Failure(msg) => s"Failure: $msg"
12.2 避免过度嵌套 #
scala
val result = data match
case Some(value) => value match
case Success(x) => s"ok: $x"
case Failure(e) => s"error: $e"
case None => "no data"
val result2 = data match
case Some(Success(x)) => s"ok: $x"
case Some(Failure(e)) => s"error: $e"
case None => "no data"
12.3 使用模式守卫简化 #
scala
val result = x match
case n if n > 0 => "positive"
case n if n < 0 => "negative"
case _ => "zero"
十三、总结 #
模式类型 #
| 模式类型 | 示例 |
|---|---|
| 常量模式 | case 0 => … |
| 变量模式 | case n => … |
| 类型模式 | case x: Int => … |
| 构造器模式 | case Person(name, age) => … |
| 序列模式 | case List(1, 2, _*) => … |
| 元组模式 | case (x, y) => … |
| 提取器模式 | case Even(half) => … |
最佳实践 #
- 使用 sealed trait 确保穷尽性
- 利用模式匹配替代 if-else 链
- 使用模式守卫增加灵活性
- 自定义提取器扩展匹配能力
下一步,让我们学习 循环语句!
最后更新:2026-03-27