Scala中是否有一种方法可以在不使用if nesting的情况下转义多个return语句

时间:2014-02-26 07:05:15

标签: scala functional-programming return

我是 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语句,以及是否嵌套。

3 个答案:

答案 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个案例并仅使用它们,在这种情况下,当实现更改时,它们将在运行时遇到错误 - 时间。