0Pricing
Scala for Backend Engineering & Functional Programming · 课时

for 推导式中的 Option

串联多个 Option

for 推导式中的 Option 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

简洁地串联 Options

串联多个 flatMap 和 map 调用后,代码可能变得难以阅读。Scala 的 for 推导式为同样的操作提供了更清晰的语法。

它是一种语法糖,编译器会将其改写为 flatMap 和 map 调用。

基本的 for 推导式

在 for { ... } yield ... 中,每个 x <- option 都会在值存在时将其取出。yield 用于构建最终结果。

如果每个 Option 都是 Some,您就会得到一个包含结果的 Some。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

遇到 None 时短路

如果任何生成器是 None,整个推导式就会产生 None,后续步骤也会被跳过。

这与 flatMap 提供的短路行为相同,但更易于阅读。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = None
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

它是如何展开的

编译器会将 for 推导式改写为 flatMap 和 map。下面两段代码是等价的。

理解这一点有助于您预测结果类型。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val viaFor = for { x <- a; y <- b } yield x + y
    val viaFlatMap = a.flatMap(x => b.map(y => x + y))
    println(viaFor)
    println(viaFlatMap)
  }
}

使用前面的值

后面的生成器可以引用前面绑定的值。这样,每一步都可以依赖前一步的结果。

object Main {
  def main(args: Array[String]): Unit = {
    val base: Option[Int] = Some(10)
    val result = for {
      x <- base
      y <- Some(x * 2)
    } yield x + y
    println(result)
  }
}

中间绑定

您可以在推导式中使用 =(而不是箭头)引入普通值。这对于进行中间计算很有帮助。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(6)
    val result = for {
      x <- a
      doubled = x * 2
    } yield doubled + 1
    println(result)
  }
}

使用 if 添加守卫

推导式可以包含 if 过滤条件。如果条件不满足,结果就会变成 None。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(8)
    val even = for {
      x <- a
      if x % 2 == 0
    } yield x
    println(even)
    val b: Option[Int] = Some(7)
    println(for { x <- b if x % 2 == 0 } yield x)
  }
}

组合多个查找

一种典型用法是:查找多个键,并且仅当所有键都存在时才将它们组合起来。

object Main {
  val data = Map("a" -> 1, "b" -> 2)
  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- data.get("a")
      y <- data.get("b")
    } yield x + y
    println(combined)
    val missing = for {
      x <- data.get("a")
      z <- data.get("c")
    } yield x + z
    println(missing)
  }
}

为什么使用 for 推导式

它可以提供:

  • 清晰地按顺序处理相互依赖的 Options
  • 遇到 None 时自动短路
  • 与 flatMap/map 相同的能力,但嵌套更少
  • 使用 if 进行过滤,并使用中间 = 绑定

得到最终值

推导式产生的是一个 Option,因此请使用 getOrElse 或 fold 将其转换为普通值。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val total = (for { x <- a; y <- b } yield x + y).getOrElse(0)
    println(total)
  }
}

整合起来

完整流程:解析两个输入,检查一个条件,将结果组合起来,并提供默认值。

object Main {
  def parse(s: String): Option[Int] = s.toIntOption
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- parse("10")
      y <- parse("5")
      if y != 0
    } yield x / y
    println(result.getOrElse(-1))
  }
}

快速检查

测试您对 Option 上的 for 推导式的理解。

回顾

您已经学会使用 for 推导式串联 Options:

  • for { x <- a; y <- b } yield ... 可以清晰地按顺序处理 Options
  • 它会展开为 flatMap/map
  • 任何一个 None 都会使整个结果短路为 None
  • 后面的生成器可以使用前面的值;= 用于添加绑定;if 用于过滤
  • 最后使用 getOrElse 或 fold 得到普通值

常见问题解答

「for 推导式中的 Option」课时是免费的吗?

是的 — 「for 推导式中的 Option」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「for 推导式中的 Option」这节课中我会学到什么?

串联多个 Option 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「for 推导式中的 Option」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 避免使用 null
  2. Option 上的 map 与 flatMap
  3. getOrElse 与 fold
  4. for 推导式中的 Option
← 返回 Scala for Backend Engineering & Functional Programming