基础语法
val list = List(Some(1), None, Some(2), Some(3))
for (Some(x) <- list) {
println(x)
}
一、基本用法
1. 列表/集合中的模式匹配
val pairs = List((1, "a"), (2, "b"), (3, "c"))
for ((num, letter) <- pairs) {
println(s"数字: $num, 字母: $letter")
}
2. 过滤不匹配的元素
val mixed = List(1, "hello", 2, "world", 3)
for (x: Int <- mixed) {
println(s"整数: $x")
}
二、常见使用场景
1. 处理 Option 类型
val options = List(Some("Alice"), None, Some("Bob"), None, Some("Charlie"))
for (Some(name) <- options) {
println(s"名字: $name")
}
options.collect { case Some(name) => name }.foreach(println)
2. 处理 Map
val scores = Map("Alice" -> 85, "Bob" -> 92, "Charlie" -> 78)
for ((name, score) <- scores) {
println(s"$name 的分数: $score")
}
for ((name, score) <- scores if score > 80) {
println(s"优秀: $name ($score)")
}
3. 嵌套结构匹配
val data = List(
("Alice", Some(25)),
("Bob", None),
("Charlie", Some(30))
)
for ((name, Some(age)) <- data) {
println(s"$name 的年龄: $age")
}
三、结合守卫条件
val numbers = 1 to 10
for (x <- numbers if x % 2 == 0) {
println(s"$x 的平方: ${x * x}")
}
for {
x <- numbers
if x % 2 == 0
square = x * x
} {
println(s"$x 的平方: $square")
}
四、高级模式匹配
1. 匹配特定模式
case class Person(name: String, age: Int)
val people = List(
Person("Alice", 25),
Person("Bob", 17),
Person("Charlie", 30),
Person("David", 16)
)
for (Person(name, age) <- people if age >= 18) {
println(s"成年人: $name ($age 岁)")
}
2. 忽略部分元素
val triplets = List((1, 2, 3), (4, 5, 6), (7, 8, 9))
for ((first, _, third) <- triplets) {
println(s"第一个: $first, 第三个: $third")
}
3. 使用 @ 绑定完整模式
val list = List(List(1, 2, 3), List(4, 5), List(6, 7, 8, 9))
for (innerList @ List(a, b, _*) <- list) {
println(s"列表: $innerList, 前两个元素: $a, $b")
}
五、生成新集合(yield)
val numbers = List(1, 2, 3, 4, 5)
val doubledEvens = for {
x <- numbers
if x % 2 == 0
} yield x * 2
println(doubledEvens)
case class User(name: String, age: Int, active: Boolean)
val users = List(
User("Alice", 25, true),
User("Bob", 17, true),
User("Charlie", 30, false),
User("David", 22, true)
)
val activeAdultNames = for {
User(name, age, true) <- users
if age >= 18
} yield name
println(activeAdultNames)
六、处理失败情况
val mixedData = List(
Right("成功1"),
Left("错误1"),
Right("成功2"),
Left("错误2"),
Right("成功3")
)
val successes = for (Right(value) <- mixedData) yield value
println(successes)
val successes2 = mixedData.collect { case Right(value) => value }
七、多重生成器
val list1 = List(1, 2, 3)
val list2 = List('a', 'b', 'c')
for {
x <- list1
y <- list2
} println(s"($x, $y)")
val optionalData = List(Some(1), None, Some(2))
val letters = List('a', 'b')
for {
Some(num) <- optionalData
letter <- letters
} println(s"$num$letter")
八、实际应用示例
1. 数据清洗
val rawData = List(
("2023-01-01", Some(100.5), "USD"),
("2023-01-02", None, "USD"),
("2023-01-03", Some(200.0), "EUR"),
("2023-01-04", Some(150.75), "USD")
)
val validTransactions = for {
(date, Some(amount), currency) <- rawData
if amount > 0
} yield (date, amount, currency)
println(s"有效交易数量: ${validTransactions.size}")
2. JSON 数据处理
case class Order(id: Int, customer: String, amount: Option[Double])
val orders = List(
Order(1, "Alice", Some(100.0)),
Order(2, "Bob", None),
Order(3, "Charlie", Some(200.0)),
Order(4, "David", Some(150.0))
)
val totalAmount = (for {
Order(_, _, Some(amount)) <- orders
} yield amount).sum
println(s"总金额: $totalAmount")
注意事项
- 类型安全:
for 中的模式匹配是类型安全的
- 过滤功能:不匹配的元素会被自动过滤掉,不会抛出异常
- 性能:对于大数据集,考虑使用
view 或迭代器
- 可读性:复杂的模式匹配可能影响可读性
最佳实践
- 用于数据提取和过滤
- 结合
yield 生成新集合
- 保持模式匹配简单
- 复杂的逻辑使用
match 表达式