Scala - 连接Try()结果的数量

时间:2017-01-29 12:33:09

标签: scala

我有多个接口,其中每个返回Try()结果。

例如:

def getElements1(id: Guid): Try[Seq[SpecialElement]] //From interface A
def getElements2(id: Guid): Try[Seq[SpecialElement]] //From interface B
def getElements3(id: Guid): Try[Seq[SpecialElement]] //From interface C

全部独立,可以随机失败。

什么是最好的Scala方式'连接Failure()案例的输出也是如此?

2 个答案:

答案 0 :(得分:2)

你可以用于理解:

case class SpecialElement(x: Int)

val x: Try[Seq[SpecialElement]] = Try(List(SpecialElement(1)))
val y: Try[Seq[SpecialElement]] = Try(List(SpecialElement(2)))
val z: Try[Seq[SpecialElement]] = Try(List(SpecialElement(3)))

for {
  a <- x
  b <- y
  c <- z
} yield a ++ b ++ c 
Success(List(SpecialElement(1), SpecialElement(2), SpecialElement(3)))

for {
  a <- x
  b <- y
  c <- Try(throw new Exception)
} yield a ++ b ++ c 
Failure(java.lang.Exception)

答案 1 :(得分:2)

嗯...... nicest 'Scala way'取决于您的要求是什么?

所以...你有3 def s,

def getElements1(id: Guid): Try[Seq[SE]]
def getElements2(id: Guid): Try[Seq[SE]]
def getElements3(id: Guid): Try[Seq[SE]]

案例1 - 结果失败,如果其中至少有1个失败并且您只得到1个失败的错误。

val result: Try[Seq[SE]] = for {
  emements1 <- getElements1(id)
  emements2 <- getElements2(id)
  emements3 <- getElements3(id)
} yield emements1 ++ emements2 ++ emements3

案例2 - 结果失败,如果其中至少有1个失败并且您希望仅获得所有失败的错误,

def trySeqToEither[T](tryTSeq: Seq[Try[T]]): Either[Seq[Throwable], Seq[T]] = {
  val accInit: Either[Seq[Throwable], Seq[T]] = Right(Seq.empty[T])

  tryTSeq.aggregate(accInit)({
    case (Right(seq), Success(t)) => Right(seq :+ t)
    case (Right(seq), Failure(ex)) => Left(Seq[Throwable](ex))
    case (Left(seq), Success(t)) => Left(seq)
    case (Left(seq), Failure(ex)) => Left(seq :+ ex) 
  })
}

val seqResultEither: Either[Seq[Throwable], Seq[Seq[SE]]]  = trySeqToEither(
    Seq(getElements1(id), getElements2(id), getElements3(id))
)

val resultEither: Either[Seq[Throwable], Seq[SE]] = seqResultEither match {
  case Right(seqResult) => Right(seqResult.flatten)
  case Left(seqThrowable) => Left(seqThrowable)
}

案例3 - 结果忽略失败的计算

val emementsOption1 = getElements1(id).toOption
val emementsOption1 = getElements2(id).toOption
val emementsOption3 = getElements3(id).toOption

val result: Seq[SE] = Seq[Seq[SE]](emementsOption1, emementsOption2, emementsOption3).flatten