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

getOrElse 与 fold

提取值

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

取出值

最终,您需要从 Option 中提取普通值,并在它为 None 时提供合理的值。

Scala 提供了 getOrElse 和 fold 等安全的提取方法。

使用 getOrElse

getOrElse 会返回 Some 中的值;如果是 None,则返回您提供的默认值。

它始终返回普通值,而不会返回 Option。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(5)
    val b: Option[Int] = None
    println(a.getOrElse(0))
    println(b.getOrElse(0))
  }
}

默认值是惰性的

getOrElse 中的默认值只有在 Option 为 None 时才会求值。因此,当值存在时,计算昂贵的默认值不会产生任何开销。

object Main {
  def expensiveDefault(): Int = { println("computing default"); 99 }
  def main(args: Array[String]): Unit = {
    val present: Option[Int] = Some(7)
    println(present.getOrElse(expensiveDefault()))
  }
}

避免使用 get

Option 提供了 get 方法,但它在遇到 None 时会抛出异常。这违背了使用 Option 的初衷。

请改用 getOrElse、fold 或模式匹配。

使用 orElse 提供备用 Option

orElse 的作用不同:如果第一个 Option 是 Some,它就返回第一个 Option;否则返回备用的 Option。

当您要依次尝试多个本身可能为空的备选项时,可以使用它。

object Main {
  def main(args: Array[String]): Unit = {
    val primary: Option[Int] = None
    val backup: Option[Int] = Some(42)
    println(primary.orElse(backup))
  }
}

介绍 fold

fold 可以在一次调用中处理两种情况。您先为 None 提供默认值,再为 Some 中的值提供函数。

它会返回单个结果,并在值存在时对其进行转换。

object Main {
  def main(args: Array[String]): Unit = {
    val n: Option[Int] = Some(10)
    val result = n.fold(0)(x => x * 2)
    println(result)
  }
}

None 上的 fold

当 Option 为 None 时,fold 会返回您先提供的默认值,并忽略转换函数。

object Main {
  def main(args: Array[String]): Unit = {
    val empty: Option[Int] = None
    val result = empty.fold(-1)(x => x * 2)
    println(result)
  }
}

fold 转换为其他类型

fold 的两个分支必须返回相同类型,但该类型可以不同于 Option 中值的类型。

这里我们将 Option[Int] 转换为 String。

object Main {
  def describe(o: Option[Int]): String =
    o.fold("missing")(x => s"value $x")
  def main(args: Array[String]): Unit = {
    println(describe(Some(8)))
    println(describe(None))
  }
}

如何选择

快速指南:

  • getOrElse:提供一个相同类型的默认值
  • orElse:提供一个备用 Option
  • fold:在一个步骤中转换值并提供默认值
  • 模式匹配:适合每种情况都需要更多逻辑时

与 map 组合

一种常见写法是先使用 map 进行转换,再使用 getOrElse 得到普通值。

object Main {
  def main(args: Array[String]): Unit = {
    val name: Option[String] = Some("ada")
    val display = name.map(_.toUpperCase).getOrElse("ANON")
    println(display)
  }
}

整合起来

查找配置值,提供备用 Option,然后使用 getOrElse 得到默认值。

object Main {
  val env = Map("timeout" -> "30")
  def main(args: Array[String]): Unit = {
    val timeout = env.get("timeout")
      .flatMap(_.toIntOption)
      .getOrElse(60)
    println(timeout)
    val retries = env.get("retries").fold(3)(_.toInt)
    println(retries)
  }
}

快速检查

测试您对提取 Option 值的理解。

回顾

您已经学会安全地提取 Option 值:

  • getOrElse(default) 返回该值或默认值(以惰性方式求值)
  • orElse(fallback) 返回第一个 Some 或备用 Option
  • fold(default)(f) 在一个步骤中转换 Some,并为 None 提供默认值
  • 避免使用 get,因为它会在 None 时抛出异常

常见问题解答

「getOrElse 与 fold」课时是免费的吗?

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

「getOrElse 与 fold」这节课中我会学到什么?

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

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

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

「getOrElse 与 fold」课时需要多长时间?

大多数 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