【问题标题】:Unwrapping a Guava Optional in a single expression在单个表达式中展开 Guava Optional
【发布时间】:2012-11-26 05:51:09
【问题描述】:

作为同时在 GWT 工作的 Scala 开发人员,我欢迎将 Optional 添加到 Guava。

Optional 最常见的用例之一是从方法返回可选值(正如What's the point of Guava's Optional class 的答案所建议的那样。

在scala中,我经常这样写代码:

def someExpensiveOperation(params: Type): Option[ResultType] = ...
someExpensiveOperation(params).foreach({ val =>
  doSomethingWithVal (val)
})

Guava 的 Option 似乎不允许任何比这样更优雅的东西:

Optional<MyType> optionalResponse = someExpensiveOperation(params);
if (optionalResponse.isPresent()) {
    doSomethingWithVal(optionalResponse.get())
}

局部变量是多余的,它需要重复一个可以抽象的模式(if (optional.isPresent()) { doSomethingWith(optional.get()) })。

另一种选择是调用两次返回Optional的方法:

if (someExpensiveOperation(params).isPresent()) {
    doSomethingWithVal(someExpensiveOperation(params).get())
}

但这显然是不可取的,因为它不必要地多次调用昂贵的操作。

我很好奇其他人是如何处理这种非常常见的情况的(可能是通过编写像 &lt;T&gt;useIfPresent(Optional&lt;T&gt; val, Closure&lt;? super T&gt; closure) 这样的静态实用程序方法?),或者是否有人找到了更优雅的解决方案。

另外,如果有人知道为什么像 Optional.foreach(Closure&lt;? super T&gt; closure)(但希望命名更好)这样的方法被省略了,我很想知道其中的原因。

【问题讨论】:

    标签: java guava


    【解决方案1】:

    它不存在是因为我们觉得编写闭包的匿名类笨拙更笨拙且可读性更差——至少在 Java 中,不一定在 Scala 中——比你已经编写的局部变量和 if 语句.

    也就是说,另一种选择是

    for (Foo x : someExpensiveOperation().asSet()) {
      // do stuff with x
    }
    

    注意这里asSet 是必要的——Optional 非常刻意地不实现Iterable

    【讨论】:

    • 有点 OT,但我想知道为什么 Optional.asSet() 返回 Set 而不是 ImmutableSet 因为它被记录为返回不可变的。是因为Optional 是在c.g.c.base 中而不是c.g.c.collect 中发货的吗?
    • 就是这样。 (Google 的构建系统或多或少禁止循环包依赖。)
    • 这完全合理。我经常在以干净的函数方式做事与 Java 缺乏闭包之间的内在冲突作斗争。话虽如此,我使用 IntelliJ 自动将匿名内部类折叠成 JDK 8 风格的闭包语法。沿着这些思路,当 Java 8 接近发布时,是否有计划重新审视基于匿名类冗长的设计决策?
    • 重新访问?可能。 Google 仍在向 JDK7 迁移,更不用说 8 了;在可预见的未来,我们有很多用户将使用 JDK 5。我们会看看会发生什么。
    • JDK 5?这太糟糕了。 Guava 的标语是“Guava: Google Core Libraries for Java 1.6+”:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2013-09-04
    • 2012-02-15
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多