如果设置了选项的值,我希望执行一些逻辑。
来自java背景,我使用了:
if (opt.nonEmpty) {
//something
}再深入到scala,我可以这样写:
opt.foreach(o => {
//something
})哪一个更好?"foreach“一词听起来更像是”惯用“,而不是Java,但它的可读性较低--应用于单个值的"foreach”听起来很奇怪。
发布于 2013-08-10 16:32:51
您的示例不完整,也没有使用最少的语法。只需比较这两个版本:
if (opt.nonEmpty) {
val o = opt.get
// ...
}
// vs
opt foreach {
o => // ...
}和
if (opt.nonEmpty)
doSomething(opt.get)
// vs
opt foreach doSomething在这两个版本中,if解决方案中都存在更多的语法开销,但我同意,如果只将foreach视为一个可选值,则Option上的foreach可能会使人感到困惑。
相反,foreach描述了您想要做一些副作用,如果您认为Option是一个monad,而foreach只是一种转换它的方法,这是很有意义的。使用foreach还有一个很大的好处,那就是它使重构变得更容易--您只需将其类型更改为List或任何其他monad,就不会出现任何编译器错误(因为Scalas很棒的集合库,您不必只使用在monad上工作的操作,在很多类型上定义了很多方法)。
发布于 2013-08-10 16:25:28
如果您认为foreach是一个List,但最多只有一个元素,那么它是有意义的。
一个更整洁的风格,国际海事组织,是使用一个理解:
for (o <- opt) {
something(o)
}发布于 2013-08-10 16:31:10
如果您认为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。
https://stackoverflow.com/questions/18163828
复制相似问题