如果设置了选项的值,我想执行一些逻辑。
来自java背景,我用过:
if (opt.nonEmpty) {
//something
}
再深入一点,我可以这样写:
opt.foreach(o => {
//something
})
哪一个更好?“foreach” 听起来更“惯用”,Java 更少,但可读性更差——应用于单个值的“foreach”听起来很奇怪。
如果设置了选项的值,我想执行一些逻辑。
来自java背景,我用过:
if (opt.nonEmpty) {
//something
}
再深入一点,我可以这样写:
opt.foreach(o => {
//something
})
哪一个更好?“foreach” 听起来更“惯用”,Java 更少,但可读性更差——应用于单个值的“foreach”听起来很奇怪。
您的示例不完整,并且您没有使用最少的语法。只需比较这两个版本:
if (opt.nonEmpty) {
val o = opt.get
// ...
}
// vs
opt foreach {
o => // ...
}
和
if (opt.nonEmpty)
doSomething(opt.get)
// vs
opt foreach doSomething
在这两个版本中,解决方案都有更多的语法开销if
,但我同意,如果您仅将其视为可选值, foreach
on an可能会令人困惑。Option
相反foreach
,它描述了您想要做某种副作用,如果您认为自己Option
是一个 monad 并且foreach
只是一种转换它的方法,那么这很有意义。此外, Usingforeach
的巨大优势在于它使重构更容易 - 您可以将其类型更改为 aList
或任何其他 monad,并且不会出现任何编译器错误(因为 Scalas 强大的集合库,您不会被限制只使用适用于monads,在很多类型上定义了很多方法)。
foreach
does make sense, if you think of Option
as being like a List
, but with a maximum of one element.
A neater style, IMO, is to use a for-comprehension:
for (o <- opt) {
something(o)
}
foreach
Option
如果您认为是一个最多可以包含一个值的列表,那么这是有道理的。这也导致了对许多其他可用方法的正确直觉Option
。
在这种情况下,我至少可以想到一个您可能更喜欢的重要原因foreach
:它消除了可能的运行时错误。使用这种nonEmpty
方法,您有时必须执行一个get
*,如果您不小心忘记检查是否为空,这可能会使您的程序严重崩溃。
如果你完全get
从你的脑海中抹去以避免那种错误,副作用是你也少用了nonEmpty
!而且您将开始享受并让编译器处理如果碰巧为空foreach
应该发生的事情。Option
你会看到这个概念出现在其他地方。你永远不会做
if (age.nonEmpty)
Some(age.get >= 18)
else
None
你更愿意看到的是
age.map(_ >= 18)
原则是您希望避免编写处理失败情况的代码——您希望将这种负担卸载给编译器。许多人会告诉你,你永远不应该使用get
,无论你认为你对预检查有多小心。所以这让事情变得更容易。
* 除非您实际上只是想知道 是否Option
包含一个值并且并不真正关心该值,在这种情况下nonEmpty
就可以了。在这种情况下,它充当一种toBoolean
.
我在其他答案中没有找到的东西:
使用 时if
,我更喜欢前者if (opt isDefined)
,if (opt nonEmpty)
因为前者不像集合,并且更清楚地表明我们正在处理一个选项,但这可能是一个品味问题。
if
并且foreach
在某种意义上是不同的,即在返回if
时将返回值的表达式。因此,在某种程度上, using甚至比 更类似于java,因为 java 有一个 foreach 循环,而 java's不是表达式。使用 for 理解更类似于 scala。foreach
Unit
foreach
if
if
您也可以使用模式匹配(但这也不太惯用)
您可以使用该fold
方法,它采用两个函数,因此您可以在 case 中评估一个表达式,在Some
case中评估另一个表达式None
。由于类型推断的工作原理,您可能需要显式指定预期类型(如此处所示)。所以在我看来,有时使用模式匹配或val result = if (opt isDefined) expression1 else expression2
.
如果您不需要返回值并且确实不需要处理未定义的情况,则可以使用foreach
.