48

为什么使用foreach,mapflatMap被认为比使用getScala 选项更好?如果我使用isEmpty,我可以get安全地打电话。

4

6 回答 6

84

嗯,它有点回到“告诉,不要问”。考虑这两行:

if (opt.isDefined) println(opt.get)
// versus
opt foreach println

在第一种情况下,您正在查看内部opt,然后根据您所看到的做出反应。在第二种情况下,你只是告诉opt你想要做什么,然后让它处理它。

第一种情况对 . 了解太多Option,复制了它内部的逻辑,很脆弱并且容易出错(如果编写不正确,它可能导致运行时错误,而不是编译时错误)。

除此之外,它不是可组合的。如果你有三个选项,一个 for comprehension 会处理它们:

for {
  op1 <- opt1
  op2 <- opt2
  op3 <- opt3
} println(op1+op2+op3)

有了if,事情开始变得一团糟。

于 2011-07-25T19:09:07.160 回答
22

使用嵌套选项的一个很好的理由foreach是解析某些内容。如果你有类似的东西

val nestedOption = Some(Some(Some(1)))
for {
  opt1 <- nestedOption
  opt2 <- opt1
  opt3 <- opt2
} println(opt3)

控制台打印1. 如果您将其扩展到您有一个类可以选择存储对某物的引用的情况,该类又存储另一个引用,因为理解允许您避免 None/Some 检查的巨大“金字塔”。

于 2011-07-25T17:29:58.973 回答
19

实际问题已经有了很好的答案,但对于更多Option-foo ,您绝对应该查看Tony Morris 的 Option Cheat Sheet

于 2011-07-25T21:27:24.993 回答
6

map将,foreachflatMap直接应用到Option而不是使用get然后执行该功能更有用的原因是它可以在Some or None上运行,并且您不必进行特殊检查以确保该值存在。

val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1  // doesn't work if x is None

这里的结果y是一个Option[Int],这是可取的,因为如果x是可选的,那么y也可能是未确定的。由于get不工作None,你必须做一堆额外的工作来确保你没有得到任何错误;为您完成的额外工作map

于 2011-07-25T16:48:41.083 回答
2

简单地说:

  • 如果您需要做某事(当您不需要捕获每次调用的返回值时的过程),仅当定义了选项(即是 a Some):使用foreach(如果您关心每次调用的结果,请使用map

  • 如果您需要在选项定义的情况下执行某些操作,如果不是,则需要执行其他操作:isDefined在 if 语句中使用

  • 如果选项是 a 则需要该值,如果是 a 则需要Some默认值None:使用getOrElse

于 2016-10-14T06:19:21.767 回答
0

尝试以 get更加命令式的方式执行我们的操作,您需要告诉您该做什么以及如何做。换句话说,我们正在口授事物并更多地挖掘Options内部结构。哪里 map,flatmap 有更实用的做事方式,我们只说要做什么而不是怎么做

于 2016-10-14T07:01:49.673 回答