如何干净地验证函数输入和 return Scala 中的 Future

How to cleanly validate function inputs and return a Future in Scala

我有一个函数(我删除了类型,因为我更关心如何将它们拼凑在一起):

def func(opt1: Option, opt2: Option) = Future {
  for {
    o1 <- opt1
    o2 <- opt2
  } functionThatReturnsAFuture(o1, o2)
  Future.successful()
}

我正在尝试验证这些选项,然后调用我的 return 未来的函数,但我不知道如何在惯用的 Scala 中执行此操作。

如果我这样做:

def func(opt1: Option, opt2: Option) = Future {
  for {
    o1 <- opt1
    o2 <- opt2
  } yield functionThatReturnsAFuture(o1, o2)
}

它自然会return一个选项[Future]。

我也可以 opt1.flatMap(opt2.map(functionThatReturnsAFuture)).sequence 但这仍然很难看。

是否有任何惯用的 scala(或 scala + cat)方式来进行这样的验证并 returning the Future?

谢谢!

您可以使用 Scala 优雅地解决这个问题。在任何情况下,您都需要处理其中一个选项是 none 或两个选项都是 none.

的情况

Return 如果其中一个或两个值是 none.

,则 Future 失败
case class NoneFoundException(msg: String) extends Exception(msg)

def func(opt1: Option, opt2: Option) = {
 val result = 
  for {
    value1 <- opt1
    value2 <- opt2
  } yield someFutureReturningFunction(value1, value2)

 result.getOrElse {
  Future.failed(NoneFoundException("one or both of opt1, opt2 are none."))
 }

}

与类型而不是异常进行通信

sealed trait Result[+A]

case class ReturnedValue[+A](value: A) extends Result[A]

case class NoneFound extends Result[Nothing]

 def func(opt1: Option, opt2: Option) = {
  val result = 
   for {
     o1 <- opt1
     o2 <- opt2
   } functionThatReturnsAFuture(o1, o2).map(value => ReturnedValue(value))

  result.getOrElse {
   NoneFound
  }

}

现在函数的return类型是Future而不是Future的Option