如果设置了选项的值,我想执行一些逻辑.
来自java背景,我用过:
if (opt.nonEmpty) {
//something
}
Run Code Online (Sandbox Code Playgroud)
进一步了解scala,我可以写为:
opt.foreach(o => {
//something
})
Run Code Online (Sandbox Code Playgroud)
哪一个更好?"foreach"听起来更"惯用"而且Java更少,但它的可读性更低 - 应用于单个值的"foreach"听起来很奇怪.
kir*_*uku 18
您的示例不完整,并且您不使用最小语法.只需比较这两个版本:
if (opt.nonEmpty) {
val o = opt.get
// ...
}
// vs
opt foreach {
o => // ...
}
Run Code Online (Sandbox Code Playgroud)
和
if (opt.nonEmpty)
doSomething(opt.get)
// vs
opt foreach doSomething
Run Code Online (Sandbox Code Playgroud)
在两个版本中有更多的句法开销if的解决方案,但我认为,foreach在一个Option可能会造成混淆,如果你认为它只是作为一个可选值.
而是foreach描述你想要做某种副作用,如果你想Option成为一个monad并且foreach只是一个改变它的方法,那么这很有意义.使用foreach还有一个很大的优点,它使重构更容易 - 你可以只改变它的类型List或任何其他monad你不会得到任何编译器错误(因为Scalas伟大的集合库你不限制只使用工作的操作monads,在很多类型上定义了很多方法).
Ben*_*mes 10
foreach确实有意义,如果你认为Option它像一个List,但最多只有一个元素.
一个更整洁的风格,IMO,是使用理解:
for (o <- opt) {
something(o)
}
Run Code Online (Sandbox Code Playgroud)
foreach如果你认为Option是一个最多只能包含一个值的列表,那就有意义了.这也导致了对可用的许多其他方法的正确直觉Option.
foreach在这种情况下,我至少可以想到您可能想要的一个重要原因:它可以消除可能的运行时错误.通过这种nonEmpty方法,你将在某一点上必须做一个get*,如果你偶然忘记检查空虚,这可能会使你的程序崩溃.
如果你完全get从头脑中消除以避免这种错误,那么副作用就是你也没那么用了nonEmpty!并且你将开始享受foreach并让编译器处理如果Option恰好是空的应该发生的事情.
你会看到这个概念在其他地方出现.你永远不会这样做
if (age.nonEmpty)
Some(age.get >= 18)
else
None
Run Code Online (Sandbox Code Playgroud)
你宁愿看到的是什么
age.map(_ >= 18)
Run Code Online (Sandbox Code Playgroud)
原则是您希望避免编写处理故障情况的代码 - 您希望将此负担卸载到编译器.许多人会告诉你,你永远不应该使用get,不管你认为你是在预先检查.这样可以简化事情.
*除非你实际上只想知道是否Option包含一个值并且不关心该值,在这种情况下nonEmpty就可以了.在这种情况下,它可以作为一种toBoolean.
| 归档时间: |
|
| 查看次数: |
1954 次 |
| 最近记录: |