首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >if (Option.nonEmpty)诉Option.foreach

if (Option.nonEmpty)诉Option.foreach
EN

Stack Overflow用户
提问于 2013-08-10 16:14:58
回答 4查看 3.1K关注 0票数 9

如果设置了选项的值,我希望执行一些逻辑。

来自java背景,我使用了:

代码语言:javascript
复制
if (opt.nonEmpty) {
   //something
}

再深入到scala,我可以这样写:

代码语言:javascript
复制
opt.foreach(o => {
  //something 
})

哪一个更好?"foreach“一词听起来更像是”惯用“,而不是Java,但它的可读性较低--应用于单个值的"foreach”听起来很奇怪。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-10 16:32:51

您的示例不完整,也没有使用最少的语法。只需比较这两个版本:

代码语言:javascript
复制
if (opt.nonEmpty) {
  val o = opt.get
  // ...
}

// vs

opt foreach {
  o => // ...
}

代码语言:javascript
复制
if (opt.nonEmpty)
  doSomething(opt.get)

// vs

opt foreach doSomething

在这两个版本中,if解决方案中都存在更多的语法开销,但我同意,如果只将foreach视为一个可选值,则Option上的foreach可能会使人感到困惑。

相反,foreach描述了您想要做一些副作用,如果您认为Option是一个monad,而foreach只是一种转换它的方法,这是很有意义的。使用foreach还有一个很大的好处,那就是它使重构变得更容易--您只需将其类型更改为List或任何其他monad,就不会出现任何编译器错误(因为Scalas很棒的集合库,您不必只使用在monad上工作的操作,在很多类型上定义了很多方法)。

票数 18
EN

Stack Overflow用户

发布于 2013-08-10 16:25:28

如果您认为foreach是一个List,但最多只有一个元素,那么它是有意义的。

一个更整洁的风格,国际海事组织,是使用一个理解:

代码语言:javascript
复制
for (o <- opt) {
  something(o)
}
票数 10
EN

Stack Overflow用户

发布于 2013-08-10 16:31:10

如果您认为foreach是一个最多可以包含单个值的列表,那么Option是有意义的。这也导致了对Option可用的许多其他方法的正确直觉。

在这种情况下,我至少可以想到一个您希望使用foreach的重要原因:它删除了可能的运行时错误。使用nonEmpty方法,您将不得不在某一时刻执行get*,如果您意外地忘记了一次检查空值,这会使您的程序崩溃。

如果你把get从你的脑海中完全抹去以避免这类错误,副作用就是你对nonEmpty的使用也少了!您将开始享受foreach,并让编译器处理如果Option碰巧是空的应该发生什么。

你会看到这个概念出现在其他地方。你永远不会这么做

代码语言:javascript
复制
if (age.nonEmpty)
    Some(age.get >= 18)
else
    None

你宁愿看到的是

代码语言:javascript
复制
age.map(_ >= 18)

原则是,您希望避免编写处理失败案例的代码--您希望将该负担卸给编译器。许多人会告诉您,您不应该使用get,无论您认为自己对预检查有多么谨慎。这样事情就简单多了。

*除非您实际上只是想知道Option是否包含一个值,并且并不真正关心这个值,否则nonEmpty就很好了。在这种情况下,它充当了一种toBoolean

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18163828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档