模式匹配-基础使用

53 阅读5分钟

一、问题分析与解决:从 if-else 到模式匹配

场景需求

根据省份编码(如 "42")输出对应的省份名称(如 "湖北"),先通过if-else实现基础逻辑,再用 Scala 特有的match case(模式匹配)优化,对比两种方式的差异。

1. 用 if-else 实现省份编码查询

代码如下:

/**
 * 用if-else实现省份编码查询
 * 功能:输入省份编码,返回对应省份名称
 */
object ProvinceCodeLookupByIfElse {
  def main(args: Array[String]): Unit = {
    // 测试用例:可替换为任意编码(如"33"、"11"、"99")
    val code = "42"
    // 调用方法获取省份名称
    val provinceName = getProvinceName(code)
    // 打印结果
    println(s"省份编码 $code 对应的省份是:$provinceName")
  }

  /**
   * 根据编码查询省份名称(if-else版)
   * @param code 省份编码(字符串类型)
   * @return 对应的省份名称,无匹配则返回提示语
   */
  def getProvinceName(code: String): String = {
    if (code == "42") {
      "湖北"
    } else if (code == "33") {
      "浙江"
    } else if (code == "11") {
      "北京"
    } else if (code == "31") {
      "上海"
    } else {
      "未找到对应的省份"
    }
  }
}

2. 用 match case 重构(替代 Java 的 switch-case)

/**
 * 用match case实现省份编码查询(优化版)
 * 功能:简化if-else嵌套,更直观的模式匹配
 */
object ProvinceCodeLookupByMatchCase {
  def main(args: Array[String]): Unit = {
    // 多组测试用例,验证不同场景
    val testCodes = List("33", "11", "31", "99")
    testCodes.foreach { code =>
      val provinceName = getProvinceName(code)
      println(s"省份编码 $code 对应的省份是:$provinceName")
    }
  }

  /**
   * 根据编码查询省份名称(match case版)
   * @param code 省份编码(字符串类型)
   * @return 对应的省份名称,无匹配则返回提示语
   */
  def getProvinceName(code: String): String = code match {
    case "42" => "湖北"    // 匹配编码"42",返回"湖北"
    case "33" => "浙江"    // 匹配编码"33",返回"浙江"
    case "11" => "北京"    // 匹配编码"11",返回"北京"
    case "31" => "上海"    // 匹配编码"31",返回"上海"
    case _ => "未找到对应的省份" // 通配符_,匹配所有未命中的情况
  }
}

二、match case 核心语法讲解

1. 基本格式(对比 Java 的 switch-case)

特性Scala match caseJava switch-case
语法结构表达式式(可直接返回值)语句式(需手动 break,否则穿透)
匹配类型支持任意类型(字符串、数字、对象等)仅支持基本类型、字符串(Java 7+)
默认匹配case _default
代码简洁性无嵌套,一行匹配 + 返回需 break,嵌套繁琐

Scala match case 标准格式

// 基础格式
待匹配值 match {
  case 匹配模式1 => 匹配成功后的逻辑/返回值
  case 匹配模式2 => 匹配成功后的逻辑/返回值
  // ... 更多匹配模式
  case _ => 所有模式都不匹配时的逻辑/返回值(可选,但建议加)
}

2. 执行流程

  1. 从第一个case开始,依次匹配 “待匹配值” 与 “匹配模式”;
  2. 一旦匹配成功,执行该case后的逻辑 / 返回值,自动终止匹配(无需像 Java 一样写 break);
  3. 若所有case都不匹配,执行case _(通配符)对应的逻辑;
  4. 若未定义case _且无匹配项,会抛出MatchError异常(建议始终添加)。

3. 基础示例:数字匹配英文名称

【教师演示】通过数字匹配对应的英文单词,巩固match case语法:

/**
 * 基础示例:数字匹配对应的英文名称
 * 演示match case的基本使用流程
 */
object NumberToEnglishDemo {
  def main(args: Array[String]): Unit = {
    // 测试不同数值(1-5、6、负数)
    val testNums = List(1, 3, 5, 6, -1)
    testNums.foreach { num =>
      val englishName = getNumberEnglish(num)
      println(s"数字 $num 对应的英文是:$englishName")
    }
  }

  /**
   * 将数字转换为对应的英文单词
   * @param num 待转换的整数
   * @return 对应的英文单词,无匹配则返回"Other"
   */
  def getNumberEnglish(num: Int): String = num match {
    case 1 => "One"    // 匹配数字1,返回"One"
    case 2 => "Two"    // 匹配数字2,返回"Two"
    case 3 => "Three"  // 匹配数字3,返回"Three"
    case 4 => "Four"   // 匹配数字4,返回"Four"
    case 5 => "Five"   // 匹配数字5,返回"Five"
    case _ => "Other"  // 匹配所有其他数字,返回"Other"
  }
}

三、扩展示例:增强版模式匹配

1. 匹配多值(同一结果)

多个模式匹配同一结果时,用|分隔:

/**
 * 扩展示例1:多模式匹配同一结果
 * 演示"|"的使用(如匹配所有偶数)
 */
object MultiPatternDemo {
  def main(args: Array[String]): Unit = {
    val num = 4
    val result = num match {
      case 1 | 3 | 5 | 7 | 9 => "奇数"  // 匹配1/3/5/7/9,返回"奇数"
      case 2 | 4 | 6 | 8 | 10 => "偶数" // 匹配2/4/6/8/10,返回"偶数"
      case _ => "非1-10的数字"
    }
    println(s"数字 $num 是:$result")
  }
}

2. 匹配类型(Scala 特有的类型匹配)

/**
 * 扩展示例2:类型匹配
 * 演示match case匹配不同数据类型
 */
object TypeMatchDemo {
  def main(args: Array[String]): Unit = {
    // 测试不同类型的值
    val testValues = List("Scala", 100, 3.14, true)
    testValues.foreach { value =>
      val typeDesc = getValueType(value)
      println(s"值 $value 的类型描述:$typeDesc")
    }
  }

  /**
   * 匹配值的类型,返回类型描述
   * @param value 任意类型的值
   * @return 类型描述字符串
   */
  def getValueType(value: Any): String = value match {
    case s: String => s"字符串类型,内容:$s"
    case i: Int => s"整数类型,值:$i"
    case d: Double => s"浮点类型,值:$d"
    case b: Boolean => s"布尔类型,值:$b"
    case _ => "未知类型"
  }
}

四、完整运行说明(可直接复制到在线 Scala 环境)

1. 在线运行环境推荐

2. 运行步骤

  1. 复制任意示例代码(如ProvinceCodeLookupByMatchCase);
  2. 粘贴到在线 Scala 运行环境的代码编辑区;
  3. 点击 “运行” 按钮,即可看到控制台输出结果;
  4. 可修改测试用例(如code值、num值),验证不同匹配场景。

3. 常见问题与注意事项

问题解决方案
抛出 MatchError确保添加case _处理所有未匹配的情况
匹配字符串时大小写问题统一转换为大写 / 小写(如code.toLowerCase match { ... }
匹配数值时类型不匹配确保待匹配值与 case 模式的类型一致(如 Int 不能匹配 Double,需手动转换)

五、总结

  1. match case是 Scala 替代 Java switch-case 的核心语法,支持表达式式返回值,无需 break;
  2. 基本格式:值 match { case 模式 => 结果 ... case _ => 默认结果 }
  3. 优势:支持任意类型匹配、多模式匹配、类型匹配,代码更简洁易读;
  4. 最佳实践:始终添加case _,避免 MatchError;匹配字符串时统一大小写,提升鲁棒性。