作为同时在GWT
工作的Scala开发人员,我欢迎向Guava添加Optional
。
我们最常见的Optional
用例之一是从方法返回可选值时(正如What's the point of Guava's Optional class的答案所示。
在scala中,我经常编写这样的代码:
def someExpensiveOperation(params: Type): Option[ResultType] = ...
someExpensiveOperation(params).foreach({ val =>
doSomethingWithVal (val)
})
Guava的选项似乎不允许比这样的东西更优雅:
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())
}
但这显然是不可取的,因为它不必要地多次调用昂贵的操作。
我很好奇其他人如何处理这个非常常见的情况(可能是通过编写像<T>useIfPresent(Optional<T> val, Closure<? super T> closure)
这样的静态实用工具?)或者是否有人找到了更优雅的解决方案。
此外,如果有人知道为什么省略了Optional.foreach(Closure<? super T> closure)
(但希望更好的名字)这样的方法,我很想知道这个理由。
答案 0 :(得分:7)
它不在那里,因为我们觉得写一个Closure的匿名类尴尬更尴尬和更不易读 - 至少在Java中,不一定在Scala中 - 比你已经编写的局部变量和if语句
那说,另一种选择是
for (Foo x : someExpensiveOperation().asSet()) {
// do stuff with x
}
请注意,此处需要asSet
- Optional
非常故意不会实施Iterable
。