在成功的Tuple2上的模式匹配

时间:2015-05-29 15:20:03

标签: scala pattern-matching type-erasure

我有2 FutureTry,我想只有在两个都成功完成时才会做某事。 Future都是独立的。所以这里有一些代码

def a1: Future[Try[String]] = Future { Success("a1") }
def a2: Future[Try[Int]] = Future { Success(2) }

val r1 = for {
  c1 <- a1
  c2 <- a2
} yield (c1, c2)
r1.map {
  case tpl: (Success[String], Success[Int]) =>
    println("success")
  case _ =>
    println("failure")
}

这会打印success。 这个问题是因为我在Tuple2上进行了模式匹配,因为即使第二个元素是Failure,第一个case被执行也会被删除。所以,如果我将a2更改为

def a2: Future[Try[Int]] = Future { Failure(new InternalError("error")) }

然后再次执行此

val r1 = for {
  c1 <- a1
  c2 <- a2
} yield (c1, c2)
r1.map {
  case tpl: (Success[String], Success[Int]) =>
    println("success")
  case _ =>
    println("failure")
}

现在,即使a2返回Failure,上述代码仍会打印success。我该如何解决?一个非常漂亮的解决方案是使用isInstanceOf[Success[String]]isInstanceOf[Success[Int]]来检查元组的元素并对其真值进行操作但是还有更好的东西吗?

1 个答案:

答案 0 :(得分:1)

您可以对元组内容进行模式匹配:

r1.map {
  case (_: Success[String], _: Success[Int]) =>
    println("success")
  case _ =>
    println("failure")
}

这样它通过调用元组的unapply方法,获取元组元素然后检查它们的类型来克服类型擦除。元组元素的运行时类型确实为SuccessFailure