模式匹配 #

一、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) => …

最佳实践 #

  1. 使用 sealed trait 确保穷尽性
  2. 利用模式匹配替代 if-else 链
  3. 使用模式守卫增加灵活性
  4. 自定义提取器扩展匹配能力

下一步,让我们学习 循环语句

最后更新:2026-03-27