假设我有三个数据库访问函数foo, bar, 并且baz每个都可以返回Option[A]某个A模型类的位置,并且调用相互依赖。
我想按顺序调用函数,并且在每种情况下,如果找不到值(None),则返回适当的错误消息。
我当前的代码如下所示:
Input is a URL: /x/:xID/y/:yID/z/:zID
foo(xID) match {
case None => Left(s"$xID is not a valid id")
case Some(x) =>
bar(yID) match {
case None => Left(s"$yID is not a valid id")
case Some(y) =>
baz(zID) match {
case None => Left(s"$zID is not a valid id")
case Some(z) => Right(process(x, y, z))
}
}
}
可以看出,代码嵌套严重。
相反,如果我使用for理解,我不能给出具体的错误信息,因为我不知道哪一步失败了:
(for {
x <- foo(xID)
y <- bar(yID)
z <- baz(zID)
} yield {
Right(process(x, y, z))
}).getOrElse(Left("One of the IDs was invalid, but we do not know which one"))
如果我使用mapand getOrElse,我最终得到的代码几乎和第一个示例一样嵌套。
这些是一种更好的结构方式来避免嵌套,同时允许特定的错误消息吗?