为什么在 Scala 的 Options 中,使用 foreach
、map
、flatMap
等方法比使用 get
更好?如果我使用 isEmpty
,那么调用get
是安全的。
为什么在 Scala 的 Options 中,使用 foreach
、map
、flatMap
等方法比使用 get
更好?如果我使用 isEmpty
,那么调用get
是安全的。
这有点涉及到"讲述,而不是询问"。考虑以下两行代码:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
在第一种情况下,你正在查看opt
中的内容,然后根据所看到的做出反应。而在第二种情况下,你只是告诉opt
你想要做什么,然后让它去处理。Option
,复制了内部逻辑,很容易出错(如果编写不正确,可能会导致运行时错误,而不是编译时错误)。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的选项小抄。
将类似于map
、foreach
和flatMap
这样的操作直接应用到Option
上,而不是使用get
然后执行函数,之所以更加有用,是因为它适用于Some
或者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
为你完成。
get
。我正在修复这篇文章。 - Michael简单来说:
如果你需要执行某些操作(不需要捕获每次调用的返回值)只有当选项已定义(即为Some
)时:使用foreach
(如果你关心每次调用的结果,使用map
)
如果你需要在选项被定义时执行某些操作,否则执行其他操作:在if语句中使用isDefined
如果你需要选项的值是Some
,或者默认值是None
:使用getOrElse
get
执行我们的操作更具命令式风格,需要告诉要做什么和如何做。换句话说,我们正在指示事情并深入挖掘Options
内部。而map, flatmap
是更功能性的做事方式,我们说要做什么但不是如何做。