五、高阶匹配(三):数组元素特征匹配
核心特性
可根据数组的元素个数、首元素值、元素特征进行灵活匹配,支持通配符_*表示任意多个后续元素。
1. 常用匹配模式
| 匹配模式 | 含义 |
|---|---|
Array(0) | 匹配长度为 1,且元素为 0 的数组 |
Array(1, x, y) | 匹配长度为 3,且首元素为 1 的数组 |
Array(0, _*) | 匹配首元素为 0,长度任意的数组 |
Array(_*) | 匹配任意数组(等同于 case _) |
2. 演示代码
/**
* 高阶匹配:数组元素特征匹配
*/
object ArrayFeatureMatchDemo {
def main(args: Array[String]): Unit = {
// 定义不同特征的数组
val arr1 = Array(0) // 长度1,元素0
val arr2 = Array(1, 2, 3) // 长度3,首元素1
val arr3 = Array(0, 2, 8, 10, 11) // 首元素0,长度5
val arr4 = Array(1, 2, 8, 10, 11) // 首元素1,长度5
// 测试每个数组的匹配结果
testArrayMatch(arr1)
testArrayMatch(arr2)
testArrayMatch(arr3)
testArrayMatch(arr4)
}
/**
* 数组特征匹配逻辑
* @param arr 待匹配的数组
*/
def testArrayMatch(arr: Array[Int]): Unit = {
arr match {
case Array(1, x, y) => println(s"数组 $arr:匹配到长度为3,且第一个元素为1")
case Array(0) => println(s"数组 $arr:匹配到长度为1,且只有一个元素0")
case Array(0, _*) => println(s"数组 $arr:匹配到长度为n,第一个元素为0")
case _ => println(s"数组 $arr:其他情况")
}
}
}
六、高阶匹配(四):案例类(样例类)匹配
核心特性
可根据样例类的类型和字段值进行精准匹配,自动解析样例类的字段,常用于面向对象场景的模式匹配。
演示代码
/**
* 高阶匹配:案例类(样例类)匹配
* 功能:匹配不同几何图形,计算对应面积
*/
object CaseClassMatchDemo {
// 定义样例类(圆、矩形)
case class Circle(radius: Double)
case class Rectangle(width: Double, height: Double)
def main(args: Array[String]): Unit = {
// 创建样例类对象
val circle = Circle(3.0)
val rectangle = Rectangle(4.0, 5.0)
val unknown = "非几何图形"
// 计算并打印面积
println(s"圆的面积:${calculateArea(circle)}")
println(s"矩形的面积:${calculateArea(rectangle)}")
println(s"未知对象的面积:${calculateArea(unknown)}")
}
/**
* 匹配样例类,计算面积
* @param shape 任意类型的几何图形/对象
* @return 图形面积(非图形返回0.0)
*/
def calculateArea(shape: Any): Double = shape match {
case Circle(r) => Math.PI * r * r // 匹配Circle类,解析半径r
case Rectangle(w, h) => w * h // 匹配Rectangle类,解析宽w、高h
case _ => 0.0 // 非图形对象返回0.0
}
}
七、变量声明中的模式匹配
核心特性
在变量声明时直接使用模式匹配,快速提取数组 / 元组的指定元素,简化代码。
1. 基础实现(无模式匹配)
/**
* 变量声明:基础实现(提取数组前3个元素)
*/
object VarDeclareBasic {
def main(args: Array[String]): Unit = {
val arr = Array(1, 2, 3, 4, 5)
// 手动通过索引提取元素
val x = arr(0)
val y = arr(1)
val z = arr(2)
println(s"x=$x, y=$y, z=$z") // 输出:x=1, y=2, z=3
}
}
2. 模式匹配实现(简化版)
/**
* 变量声明:模式匹配实现(快速提取数组元素)
*/
object VarDeclareWithMatch {
def main(args: Array[String]): Unit = {
val arr = Array(1, 2, 3, 4)
// 模式匹配提取前3个元素,_* 忽略后续所有元素
val Array(x, y, z, _*) = arr
println(s"x=$x, y=$y, z=$z") // 输出:x=1, y=2, z=3
// 元组变量声明的模式匹配
val tuple = (10, "Scala", true)
val (a, b, c) = tuple // 提取元组所有元素
println(s"a=$a, b=$b, c=$c") // 输出:a=10, b=Scala, c=true
}
}
八、守卫语句(带条件的模式匹配)
1. 基本格式
待匹配值 match {
case 模式 if 守卫条件 => 结果/逻辑 // 守卫条件为布尔表达式
// 其他case分支
case _ => 默认结果/逻辑
}
2. 基础案例:数字区间匹配(控制台输入)
import scala.io.StdIn
/**
* 守卫语句:数字区间匹配(控制台交互)
*/
object GuardMatchBasic {
def main(args: Array[String]): Unit = {
// 从控制台读取数字
println("请输入一个整数:")
val a = StdIn.readInt()
// 带守卫的模式匹配
a match {
case x if x >= 0 && x <= 3 => println(s"$x 属于区间 [0-3]")
case x if x >= 4 && x <= 8 => println(s"$x 属于区间 [4-8]")
case _ => println(s"$x 未匹配任何区间")
}
}
}
3. 进阶案例:1-100 数字特征匹配
/**
* 守卫语句:1-100数字特征匹配
* 功能:匹配大于10的偶数、大于80的奇数
*/
object GuardMatchAdvanced {
def main(args: Array[String]): Unit = {
// 遍历1-100,使用带守卫的模式匹配
for (i <- 1 to 100) {
i match {
case x if x > 10 && x % 2 == 0 => println(s"$i 是大于10的偶数")
case x if x > 80 && x % 2 != 0 => println(s"$i 是大于80的奇数")
case _ => // 忽略其他数字,不输出
}
}
}
}
九、for 表达式中的模式匹配
场景需求
从 Map 中筛选出出生年份为 1971 的创业者信息,提供两种实现方式。
1. 方式 1:for + if 守卫(基础版)
/**
* for表达式:if守卫筛选Map数据
*/
object ForMatchWithGuard {
def main(args: Array[String]): Unit = {
val m1 = Map(
"马云 - 阿里巴巴" -> 1964, "马化腾 - 腾讯" -> 1971,
"李彦宏 - 百度" -> 1968, "雷军 - 小米" -> 1969,
"丁磊 - 网易" -> 1971, "张一鸣 - 字节跳动" -> 1983,
"刘强东 - 京东" -> 1974, "程维 - 滴滴" -> 1983,
"王兴 - 美团" -> 1979, "周鸿祎 - 360" -> 1970,
"黄峥 - 拼多多" -> 1980, "李想 - 理想汽车" -> 1981,
"何小鹏 - 小鹏汽车" -> 1977, "贾跃亭 - 乐视" -> 1973,
"陈天桥 - 盛大网络" -> 1973, "周源 - 知乎" -> 1980,
"王小川 - 搜狗" -> 1978
)
// for + if守卫:筛选年份=1971的记录
println("出生年份为1971的创业者(if守卫版):")
for ((key, year) <- m1 if year == 1971) {
println(s"$key -> $year")
}
}
}
2. 方式 2:for + 模式匹配(优化版)
/**
* for表达式:模式匹配筛选Map数据
*/
object ForMatchWithPattern {
def main(args: Array[String]): Unit = {
val m1 = Map(
"马云 - 阿里巴巴" -> 1964, "马化腾 - 腾讯" -> 1971,
"李彦宏 - 百度" -> 1968, "雷军 - 小米" -> 1969,
"丁磊 - 网易" -> 1971, "张一鸣 - 字节跳动" -> 1983,
"刘强东 - 京东" -> 1974, "程维 - 滴滴" -> 1983,
"王兴 - 美团" -> 1979, "周鸿祎 - 360" -> 1970,
"黄峥 - 拼多多" -> 1980, "李想 - 理想汽车" -> 1981,
"何小鹏 - 小鹏汽车" -> 1977, "贾跃亭 - 乐视" -> 1973,
"陈天桥 - 盛大网络" -> 1973, "周源 - 知乎" -> 1980,
"王小川 - 搜狗" -> 1978
)
// for + 模式匹配:直接匹配年份=1971的记录
println("出生年份为1971的创业者(模式匹配版):")
for ((key, 1971) <- m1) {
println(s"$key -> 1971")
}
}
}
十、运行说明(可直接复制到在线 Scala 环境)
1. 推荐在线运行环境
- ScalaFiddle:scalafiddle.io/
- JDoodle:www.jdoodle.com/execute-sca…
- 菜鸟工具:c.runoob.com/compile/65S…
2. 运行步骤
- 复制任意模块的代码(如
ProvinceCodeLookupByMatch); - 粘贴到在线 Scala 编辑区,点击 “运行” 按钮;
- 可自由修改测试用例(如编码、数字、数组等),验证不同场景。
3. 核心知识点总结
match case是 Scala 替代 Java switch-case 的核心语法,支持表达式式返回值;- 基础特性:值匹配、自动终止、
case _默认匹配; - 高阶特性:元组长度匹配、类型匹配、数组特征匹配、样例类匹配;
- 扩展特性:变量声明匹配、守卫语句(带条件匹配)、for 表达式匹配;
- 最佳实践:始终添加
case _,避免MatchError;合理使用守卫语句提升匹配灵活性。