我有一些使用Java Optionals的(简化)代码:
Optional<User> maybeTarget = userRepository.findById(id1);
Optional<String> maybeSourceName = userRepository.findById(id2).map(User::getName);
Optional<String> maybeEventName = eventRepository.findById(id3).map(Event::getName);
maybeTarget.ifPresent(target -> {
maybeSourceName.ifPresent(sourceName -> {
maybeEventName.ifPresent(eventName -> {
sendInvite(target.getEmail(), String.format("Hi %s, $s has invited you to $s", target.getName(), sourceName, meetingName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
不用说,这看起来很糟糕.但我想不出另一种以较少嵌套和更易读的方式做到这一点的方法.我考虑过流式传输3个选项,但放弃了这个想法,因为做了.filter(Optional::isPresent)一个.map(Optional::get)感觉甚至更糟.
那么是否有更好的,更"Java 8"或"可选识字"的方式来处理这种情况(基本上需要多个Optionals来计算最终操作)?
我编写了Swift代码,试图从给定自定义UIView类型的所有子视图中删除所有手势识别器.
let mySubviews = self.subviews.filter() {
$0.isKindOfClass(CustomSubview)
}
for subview in mySubviews {
for recognizer in subview.gestureRecognizers {
subview.removeGestureRecognizer(recognizer)
}
}
Run Code Online (Sandbox Code Playgroud)
但该for recognizer行会产生编译错误:
'[AnyObject]?' does not have a member named 'Generator'
Run Code Online (Sandbox Code Playgroud)
我已经尝试将for recognizer循环更改为for recognizer in enumerate(subview.gestureRecognizers),但这会产生编译器错误:
Type '[AnyObject]?!' Does not conform to protocol 'SequenceType'
Run Code Online (Sandbox Code Playgroud)
我看到UIView的gestureRecognizers方法返回了[AnyObject]??,我认为双重包裹的返回值正在绊倒我.谁能帮我?
更新:修改,编译代码是:
if let recognizers = subview.gestureRecognizers {
for recognizer in recognizers! {
subview.removeGestureRecognizer(recognizer as UIGestureRecognizer)
}
}
Run Code Online (Sandbox Code Playgroud) 我有两个java.util.Optional实例,我想得到一个Optional:
是否有直接的方法来做到这一点,即是否已经有一些API来做到这一点?
以下表达式会这样做,但我必须提到第一个可选的两次:
firstOptional.isPresent() ? firstOptional : secondOptional
Run Code Online (Sandbox Code Playgroud)
这正是com.google.common.base.Optional.or()如此,但Java 8的API中不存在该方法.
aioobe接受的答案列出了一些替代方法来克服这种遗漏OptionalAPI的权利,在这种情况下必须计算这样的值(这回答了我的问题).我现在选择在我的代码库中添加一个实用程序函数:
public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试以monad风格编写语法糖std::optional.请考虑:
template<class T>
void f(std::optional<T>)
{}
Run Code Online (Sandbox Code Playgroud)
即使存在从2到2的转换,也不能使用非可选T1(例如an int)调用此函数.Tstd::optional<T>
有没有办法f接受a std::optional<T>或a T(在调用者站点转换为可选),而没有定义过载3 ?
1) f(0):error: no matching function for call to 'f(int)'和note: template argument deduction/substitution failed,(演示).
2)因为模板参数推导不考虑转换.
3)超载是用于一个一元函数的可接受的解决方案,但开始是当你有像二进制功能的烦恼operator+(optional, optional),并且是用于三元疼痛,4元,等等功能.
Java 1.8正在接收Optional类,它允许我们明确说明方法何时可以返回空值并"强制"其使用者isPresent()在使用它之前验证它是否为null().
我看到C#有Nullable,它做了类似的事情,但有基本类型.它似乎用于数据库查询,以区分值何时存在,并且当它不存在时为0并且为空.
但似乎C#的Nullable不适用于对象,仅适用于基本类型,而Java的Optional仅适用于对象而不适用于基本类型.
在C#中是否有Nullable/Optional类,这迫使我们在提取和使用它之前测试对象是否存在?
通常,您需要编写如下代码:
if someOptional != nil {
// do something with the unwrapped someOptional e.g.
someFunction(someOptional!)
}
Run Code Online (Sandbox Code Playgroud)
这似乎有点冗长,而且我听说使用!强制解包操作符可能是不安全的,最好避免使用.有没有更好的方法来处理这个?
我有以下内容Stream:
Stream<T> stream = stream();
T result = stream.filter(t -> {
double x = getX(t);
double y = getY(t);
return (x == tx && y == ty);
}).findFirst().get();
return result;
Run Code Online (Sandbox Code Playgroud)
但是,并不总是有一个结果给我以下错误:
NoSuchElementException:没有值存在
那么null如果没有价值,我怎么能回来?
给定一个String我需要获得一个Optional,如果String为null或为空,则结果为Optional.empty.我可以这样做:
String ppo = "";
Optional<String> ostr = Optional.ofNullable(ppo);
if (ostr.isPresent() && ostr.get().isEmpty()) {
ostr = Optional.empty();
}
Run Code Online (Sandbox Code Playgroud)
但肯定必须有一种更优雅的方式.
使用可选的for-in循环的正确方法是什么?
现在我总是在循环之前执行可选绑定.还有其他成语吗?
let optionalInt:[Int]? = [1, 2, 3]
if let optionalInt = optionalInt {
for i in optionalInt {
print(i)
}
}
Run Code Online (Sandbox Code Playgroud) 声明函数来映射值并在它们存在时使用它们是很方便的.
在你有几个强制对象和几个Optionals的情况下,我发现自己将其他包装在Optional.of(mandatoryObject)中,所以我可以在它们上使用相同的表达式而不用向后写它们.
Food vegetables = Food.someVegetables();
Optional<Food> condiment = Food.someCondiment();
Optional<Food> spices = Food.someSpices();
condiment.map(prepare).ifPresent(putOnPlate);
spices.map(prepare).ifPresent(putOnPlate);
Run Code Online (Sandbox Code Playgroud)
但后来我不喜欢这段代码:
putOnPlate.accept(prepare.apply(vegetables));
Run Code Online (Sandbox Code Playgroud)
所以我把它包起来:
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
Run Code Online (Sandbox Code Playgroud)
但这是错误的,因为蔬菜(在这个例子中)实际上不是可选的.它们非常重要,我给大家的印象是它们是可选的.
所以我的问题是:java中有一些类如java.util.Mandatory,所以我可以写:
Mandatory.of(vegetables).map(prepare).definitelyPresentSo(putOnPlate);
Run Code Online (Sandbox Code Playgroud)