我有两个函数:一个返回Future[Thing Or Exception]
,另一个返回Future[Boolean
。我想要一个调用两个函数并返回Future[Thing Or Exception]
的函数。如果布尔函数返回false,我想返回异常,否则返回另一个函数。
我有这样的代码但是a)我讨厌演员和b)当在“boolean gets true”路径上运行时,当我最终Await.result
在我的测试代码中返回时,我得到了这个错误:{{ 1}}。
"Promise$DefaultPromise cannot be cast to org.scalatic.Or"
我也试过了,但它在成功路径上得到了相同的Promise错误
def thingFuture: Future[Thing Or Exception]
def boolFuture: Future[Boolean]
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture
case false => Exception
}
}
// without the cast compiler says result is of type Future[Object]
result.asInstanceOf[Future[Thing Or Exception]]
}
有谁能告诉我如何用不同的回报类型撰写两个期货?谢谢!
答案 0 :(得分:2)
在发生异常的情况下,每个未来都可以通过失败状态完成,因此您只需在"快乐路径中返回thingFuture"如果boolean为false,则抛出异常。这将返回带有基础异常的Future.failed
。
val result = boolFuture.flatMap {x =>
x match {
case true => thingFuture
case false => throw new Exception("whatever")
}
}
请注意flatMap
而不是map
。因为我们将一个未来的基本价值映射到另一个未来,通过使用简单的map
,我们最终会得到Future[Future[Thing]]
。
另请注意,您可以返回Future.failed(throw new Exception("whatever"))
而不是抛出异常,结果也是相同的 - 在这两种情况下,您都会遇到失败的未来。
Or
来自scalactic,我从未使用过,但哲学仍然是一样的。你需要flatMap你的布尔未来和你的ThingOrException
未来才能结束Future[ThingOrException]
。如果您发现自己处于需要flatMap未来的情况,但其中一个case子句返回一个普通值(例如,如果是真实的返回Future[Thing]
,则在返回错误的情况下Exception
)然后你可以将普通价值包装到未来。这样所有分支都返回一个未来,flatMap将正常工作。例如:
val someOtherFuture = Future(43)
val someOrdinaryValue = 44
Future(someInteger).flatMap {
case 42 => someOtherFuture
case _ => Future(someOrdinaryValue)
}
为了简化运行时机制的内容,您还可以编写Future.successful(someOrdinaryValue)
,在这种情况下不会启动后台计算。
答案 1 :(得分:1)
据我在Scalatic文档中可以看出,您可以Right Or Left
或Good(Right)
获取Bad(Left)
的实例。
这意味着构图可能看起来像这样:
boolFuture.flatMap(b => if (b) thingFuture else Future.successful(Bad(new Exception())))
这些类型应统一为Future[Or[Thing, Exception]]