我有这个val cacheElement:Future[Option[T]]
,并且如果Option
是Some
,则期望的结果是保留未来;如果未来是,则基于其他服务创建另一个Future[Option[T]]
None
。使用模式匹配看起来像这样:
val cacheElement:Future[Option[T]] = cache.get[T](cacheKey)
for {
opt <- cacheElement flatMap {
case Some(cached) => Future { Some(cached) }
case None => createFallback(args)
}
} yield { opt match {
case Some(_) => //do something
case None => // Do something else
}
}
def createFallback[T](args:T):Future[Option[T]] = ???-
我该如何以更优雅和更轻松的方式做到这一点? Future { Some(cached) }
的重复在我看来非常冗长
答案 0 :(得分:3)
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
type T = String
val cacheElement: Future[Option[T]] = Future.successful(Some("asd"))
val failElement: Future[Option[T]] = Future.successful(None)
def createFallback: Future[T] = Future.successful("fallback")
val s = cacheElement.flatMap(_.fold(createFallback)(Future.successful))
val f = failElement.flatMap(_.fold(createFallback)(Future.successful))
Await.result(s, 1.second)
//res0: T = asd
Await.result(f, 1.second)
//res1: T = fallback
答案 1 :(得分:2)
OptionT
来自cats的monad转换器提供了orElse
这样的语法
OptionT(cacheElement) orElse OptionT(createFallback(args))
例如
import cats.data.OptionT
import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object OptionTExample extends App {
val f: Future[Option[Int]] = Future(None)
def fallback: Future[Option[Int]] = Future(Some(-1))
val v = OptionT(f) orElse OptionT(fallback)
v.value.map(println)
}
输出
Some(-1)