模式:future
深埋在条件链(if
,map
等)的深处。对于任何场景,这个深度链不满足,有一个" else" future
。
为了说明这一点,我将两个例子放在一起。
f
将条件分开,因此需要" else" future
(代码中的e
)多次指定:
def f(uo: Option[User]): Future[String] = {
val e = Future.successful("b")
// note how `e` is specified twice below
uo.map(u => if (u.id != 123) Future.successful("a") else e).getOrElse(e)
}
g
所有条件都在一起,因此" else" future
仅指定一次:
def g(uo: Option[User]): Future[String] = {
val e = Future.successful("b")
if (uo.isDefined && uo.get.id != 123) {
Future.successful("a")
} else e // note how the `e` is specified only once
}
我觉得后者更好,更具可读性,虽然我对它不是100%满意,因为uo.isDefined && uo.get...
有点,嗯,你知道,不是很好。 :)第一个uo.map(u => ...
更清晰,但我并不是100%满意,因为多次指定了e
。
使用更深入,更复杂的代码,必须进行大量解包以组合条件或不得不重复相同的条件而烦恼...#34;否则"无处不在。
问题:除了上面给出的两个方法之外,还有其他方法吗?
答案 0 :(得分:1)
您经常可以使用模式匹配来折叠嵌套:
def f(uo: Option[User]): Future[String] = uo match {
case Some(u) if u.id != 123 => Future.successful("a")
case _ => Future.successful("e") //Will match for both None and Some(123), as desired
}
您可能也对collect
方法感兴趣,该方法接受将用作地图的部分函数,并为未定义的输入返回None
:
def f(uo: Option[User]): Future[String] = uo.collect {
case u if u.id != 123 => Future.successful("a")
}.getOrElse(Future.successful("e"))