为什么使用foreach
,map
等flatMap
被认为比使用get
Scala 选项更好?如果我使用isEmpty
,我可以get
安全地打电话。
6 回答
嗯,它有点回到“告诉,不要问”。考虑这两行:
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
,事情开始变得一团糟。
使用嵌套选项的一个很好的理由foreach
是解析某些内容。如果你有类似的东西
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
控制台打印1
. 如果您将其扩展到您有一个类可以选择存储对某物的引用的情况,该类又存储另一个引用,因为理解允许您避免 None/Some 检查的巨大“金字塔”。
实际问题已经有了很好的答案,但对于更多Option
-foo ,您绝对应该查看Tony Morris 的 Option Cheat Sheet。
map
将,foreach
和flatMap
直接应用到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
。
简单地说:
如果您需要做某事(当您不需要捕获每次调用的返回值时的过程),仅当定义了选项(即是 a
Some
):使用foreach
(如果您关心每次调用的结果,请使用map
)如果您需要在选项定义的情况下执行某些操作,如果不是,则需要执行其他操作:
isDefined
在 if 语句中使用如果选项是 a 则需要该值,如果是 a 则需要
Some
默认值None
:使用getOrElse
尝试以 get
更加命令式的方式执行我们的操作,您需要告诉您该做什么以及如何做。换句话说,我们正在口授事物并更多地挖掘Options
内部结构。哪里 map,flatmap
有更实用的做事方式,我们只说要做什么而不是怎么做。