我有一些使用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来计算最终操作)?
我有以下(简化的)kotlin 代码:
data class Event(val name: String, val venue: Venue?)
data class Venue(val lat: Double, val lng: Double)
...
return events
.filter { it.venue != null }
.map { doSomething(it.venue.lat, it.venue.lng)
Run Code Online (Sandbox Code Playgroud)
该代码无法编译并出现错误Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Venue?
我明白这意味着什么,但我不明白为什么编译器无法弄清楚it.venue
不能null
在.map
调用中。
如果事件可以为空,我可以编写events.filterNotNull().name
或执行其他操作,编译器不会抱怨。有没有办法对可为空的对象属性而不是可为空的对象执行相同的操作?
谢谢你的时间
我正在尝试编写一个函数来计算2个列表的内积,即如果列表是[1,2,3]和[4,5,6]那么内积将是(1 x 4)+(2 x 5)+(3 x 6)= 4 + 10 + 18 = 32.
所以我想用来zipWith
获取产品,然后再foldl
添加它们.所以zipWith
应该产生[4,10,18],然后将foldl
它加到32.
所以我写了:
innerprod [] [] = 0
innerprod x y = foldl (+) 0 (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)
一切都编译但是当我在ghci中运行时:
Prelude ListFuncs> innerprod [1,2,3] [4,5,6]
<interactive>:3:1:
No instance for (Num
([c0] -> (a0 -> b0 -> a0) -> a0 -> [b0] -> a0))
arising from a use of `innerprod'
Possible fix:
add an instance declaration for
(Num ([c0] -> …
Run Code Online (Sandbox Code Playgroud)