守卫与绑定
匹配中的条件
守卫与绑定 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
什么是守卫条件?
守卫条件使用 if 为 case 添加布尔条件。只有模式匹配成功并且守卫条件为真时,该 case 才会匹配。
守卫条件可以根据值将一个模式细分为多个情况。
添加 if 守卫条件
将守卫条件写在模式之后:case n if n > 0 =>。如果条件为假,匹配会继续检查下一个 case。
object Main {
def sign(n: Int): String = n match {
case x if x > 0 => "positive"
case x if x < 0 => "negative"
case _ => "zero"
}
def main(args: Array[String]): Unit = {
println(sign(5))
println(sign(-3))
println(sign(0))
}
}先绑定,再设置守卫条件
守卫条件可以引用您在模式中绑定的名称。这样就能检查匹配值的属性。
object Main {
def fizz(n: Int): String = n match {
case x if x % 15 == 0 => "FizzBuzz"
case x if x % 3 == 0 => "Fizz"
case x if x % 5 == 0 => "Buzz"
case x => x.toString
}
def main(args: Array[String]): Unit = {
println(fizz(15))
println(fizz(9))
println(fizz(7))
}
}对范围使用守卫条件
守卫条件非常适合表示范围,因为字面量模式无法直接表达范围。
object Main {
def band(score: Int): String = score match {
case s if s >= 90 => "A"
case s if s >= 80 => "B"
case s if s >= 70 => "C"
case _ => "F"
}
def main(args: Array[String]): Unit = {
println(band(95))
println(band(83))
println(band(60))
}
}使用 @ 绑定模式
@ 符号可以在匹配值结构的同时,将整个匹配值绑定到一个名称。
这里的 whole @ pattern 表示:匹配 pattern,并将匹配到的值命名为 whole。
object Main {
def main(args: Array[String]): Unit = {
val x: Any = 7
val msg = x match {
case n @ (_: Int) => s"int value is $n"
case _ => "other"
}
println(msg)
}
}在集合中绑定
@ 绑定在结构化模式中尤其方便,例如在检查列表头部的同时捕获整个列表。
object Main {
def describe(xs: List[Int]): String = xs match {
case all @ (first :: _) => s"starts with $first, full = $all"
case Nil => "empty"
}
def main(args: Array[String]): Unit = {
println(describe(List(1, 2, 3)))
println(describe(Nil))
}
}组合类型模式和守卫条件
您可以将类型模式与守卫条件结合使用。系统会先检查类型,然后检查布尔条件。
object Main {
def label(x: Any): String = x match {
case s: String if s.length > 3 => "long string"
case s: String => "short string"
case _ => "not a string"
}
def main(args: Array[String]): Unit = {
println(label("hello"))
println(label("hi"))
println(label(42))
}
}多个条件
守卫条件只是一个布尔表达式,因此您可以使用 && 和 || 组合多个条件。
object Main {
def category(age: Int): String = age match {
case a if a >= 13 && a <= 19 => "teen"
case a if a < 13 => "child"
case _ => "adult"
}
def main(args: Array[String]): Unit = {
println(category(15))
println(category(8))
println(category(40))
}
}守卫条件不会贯穿执行
如果模式匹配成功但守卫条件为假,Scala 会继续检查下一个 case,而不是检查同一模式的下一个守卫条件。
请确保后续情况能够捕获未通过所有守卫条件的值。
object Main {
def test(n: Int): String = n match {
case x if x > 100 => "big"
case x => s"not big: $x"
}
def main(args: Array[String]): Unit = {
println(test(200))
println(test(5))
}
}为什么使用守卫条件和绑定?
守卫条件和 @ 绑定结合起来,可以让模式匹配更具表现力:
- 守卫条件可以添加范围和可除性等条件
@可以在解构值的同时捕获整个值- 让分支逻辑保持简洁易读
综合运用
这个示例会绑定值、检查守卫条件,并提供兜底情况。
object Main {
def temp(c: Int): String = c match {
case t if t >= 30 => s"hot ($t)"
case t if t >= 15 => s"mild ($t)"
case t => s"cold ($t)"
}
def main(args: Array[String]): Unit = {
println(temp(35))
println(temp(20))
println(temp(5))
}
}快速检查
测试您对守卫条件和绑定的理解。
回顾
您已经学会细化匹配:
- 守卫条件是模式之后的
if条件 - 如果守卫条件为假,匹配会转到下一个 case
@运算符会在解构值的同时绑定整个值- 守卫条件可以与类型模式和布尔运算符组合使用
常见问题解答
「守卫与绑定」课时是免费的吗?
是的 — 「守卫与绑定」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
「守卫与绑定」这节课中我会学到什么?
匹配中的条件 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「守卫与绑定」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?
能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。