大多数时候,我的未来业务依赖于连锁店的前期业务。大部分时间我都在使用flatMap函数和模式匹配。如;如何减少连锁期货的套期保值
findUser(userId).flatMap {
case None => Future.successful(NotFound("No user with given id"))
case Some(user) => findAddress(user.addressId).flatMap {
case None => Future.successful(NotFound("No address with given id"))
case Some(address) => findCity(address.cityId).flatMap {
case None => Future.successful(NotFound("No city with given id"))
case Some => Future.successful(Ok)
}
}
}
用这种方法我能够返回与问题相关的对象,所有分支都在处理中。但在我看来这种方法的缺点(和我的代码阅读乐趣),它嵌套了很多。此外,如果行数太长,就不可能跟踪哪种情况下的声明是哪个格式正确的。这就是编辑器的右下角。
建议的另一种方式可能会用于理解。下面是上面代码的一个等同物。但区别在于,如果if-guard不满意,comp-one将抛出异常。它也返回一个选项,使用哪个我想用我需要调用get方法(我不想这样做);
val items = for {
user <- findUser(userId) if user.isDefined
address <- findAddress(user.addressId) if address.isDefined
city <- findCity(address.cityId) if address.isDefined
} yield (user.get, address.get, city.get)
再次可能会建议捕捉异常,但我从许多来源读取捕捉异常被认为是不好的。此外,该例外不会提供哪种情况说明不符合条件。
同样的事情也适用于return语句。由于我自java和基于.net的语言,我倾向于使用下面的样式。
val user = Await.result(findUser(userId), timeout)
if (user.isEmpty) {
return Future.successful(NotFound("No user with given id"))
}
val address = Await.result(findAddress(user.get.addressId), timeout)
if (address.isEmpty) {
return Future.successful(NotFound("No address with given id"))
}
val city = Await.result(findUser(address.get.cityId), timeout)
if(city.isEmpty) {
return Future.successful(NotFound("No city with given id"))
}
Future.successful(Ok)
这在我的理解中绝对是不成问题的。首先它会导致代码块阻塞,其次它又迫使我使用get值,并使用与抛出异常类似的返回块来缩短执行时间。
一直未能找到一个优雅的解决方案。我目前正在与嵌套的方式,这使得它难以阅读
感谢
感谢,我将期待您有共享的库(也是什么monad) – Deliganli