我是 Scala 的新手。我有一个操作,需要在执行前检查前置条件。
def get(a: Option[A], b: Option[B], c: Option[C]): (Option[Error], Option[String]) = {
if (a.isEmpty)
return (Some(Error), None)
if (b.isEmpty)
return (Some(Error), None)
val ab = a.get + b.get
if (ab < null)
return (Some(Error), None)
// Some complex computations
(None, Some(str))
}
由于我不喜欢嵌套if块,我想知道是否有更好的方法来构造这段代码,排除return语句,以及是否嵌套。
答案 0 :(得分:2)
首先,我建议将返回类型更改为[错误,字符串]。
然后我不确定这种情况是否更好。
def get(a: Option[A], b: Option[B], c: Option[C]): Either[Error, String] = {
val result = for {
va <- a
vb <- b
ab = va * vb
if ab > 10
} yield {
"complex code"
}
result map { Right(_) } getOrElse Left(error)
}
答案 1 :(得分:1)
另一种方法:
def get(a: Option[A], b: Option[B], c: Option[C]) = (a, b) match {
case (None, _) => (Some(Error), None)
case (_, None) => (Some(Error), None)
case (Some(av), Some(bv)) if (av + bv < null) => (Some(Error), None)
case _ =>
// Some complex computations
(None, Some(str))
}
如果有人使用,可以进一步清理,正如@TimGreen在答案中所示。
答案 2 :(得分:1)
Tim Green回答的另一种选择:
def get(a: Option[A], b: Option[B], c: Option[C]): Either[Error, String] = (a, b) match {
case (Some(a), Some(b)) if a + b < 0 =>
Right("complex code")
case _ =>
Left(Error)
}
他对回归类型完全正确。 (Option[Error], Option[String])
有4个案例:(Some(...), Some(...))
,(Some(...), None)
等。您只返回其中2个,这非常强烈地暗示这是错误的类型。此外,您的所有函数调用者要么必须处理所有4个案例,要么从文档或查看实现中了解其中2个案例并仅使用它们,在这种情况下,当实现更改时,它们将在运行时遇到错误 - 时间。