假设我有三个数据库访问函数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"))
如果我使用map
and getOrElse
,我最终得到的代码几乎和第一个示例一样嵌套。
这些是一种更好的结构方式来避免嵌套,同时允许特定的错误消息吗?