首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >优雅地处理Scala Future[Either]]

优雅地处理Scala Future[Either]]
EN

Stack Overflow用户
提问于 2015-10-23 19:04:43
回答 2查看 5.9K关注 0票数 2

我有一种形状是这样的:

代码语言:javascript
运行
复制
val myType: Future[Either[MyError, TypeA]] = // some value

我知道我可以在这上面进行模式匹配,然后进入右或左类型,但问题是我必须嵌套我的模式匹配逻辑。我在寻找更优雅的方法来处理这件事?有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-23 19:15:26

如果将MyError编码为异常,则不再需要Either,只需针对完成操作进行patternMatch,或使用recoverWith将其映射到另一种类型:

代码语言:javascript
运行
复制
myType.onComplete {
  case Success(t) =>
  case Failure(e) =>
}

要映射现有的Either类型,可以这样做:

代码语言:javascript
运行
复制
case class MyException(e: MyError) extends Exception

def eitherToException[A](f: Future[Either[MyError,A]]): Future[A] = {
  f.flatMap {
    case Left(e) => Future.failed(MyException(e))
    case Right(x) => Future.successful(x)
  }
}

val myType2 = eitherToException(myType)

或者,如果MyErrorTypeA在您的控制下,您可以根据此创建一个常见的超级类型和模式匹配:

代码语言:javascript
运行
复制
sealed trait MyResult
final case class MyError() extends MyResult
final case class TypeA() extends MyResult

myType.map {
  case MyError() => ...
  case TypeA() => ...
}
票数 8
EN

Stack Overflow用户

发布于 2015-10-24 08:04:19

您可以创建自定义提取器对象:

代码语言:javascript
运行
复制
object FullSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Right(x)) => Some(x)
    case _ => None
  }
}

object PartSuccess {
  def unapply[T](x: Try[Either[MyError, T]]) = x match {
    case Success(Left(err)) => Some(err)
    case _ => None
  }
}

代码语言:javascript
运行
复制
val myType: Future[Either[MyError, TypeA]] = // some value

myType.onComplete {
  case FullSuccess(x) => ... // equivalent to case Success(Right(x))
  case PartSuccess(x) => ... // equivalent to case Success(Left(x))
  case Failure(e) => ...
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33309674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档