我有以下元组 - (t1,t2):(试试,尝试)
我想检查两者是否成功,或者其中一个是否失败,但避免代码重复.就像是:
(t1,t2) match {
case (Success(v1),Success(v2)) => new MyClass(v1,v2)
case (Failure(e),_) | (_,Failure(e)) => println(e.getMessage)
}
Run Code Online (Sandbox Code Playgroud)
当然第二个语句不起作用,因为我需要提供不同的提取变量.但是我必须检查它们,因为我不知道哪个失败并且实际上包含Throwable.我希望Try会像Future一样行动,所以它会有Try.sequence(t1,t2).
知道如何使这项工作优雅吗?
你可以把它转换成Try[MyClass]这样的:
val myclass = for {
v1 <- t1
v2 <- t2
} yield new MyClass(v1, v2)
Run Code Online (Sandbox Code Playgroud)
如果t1失败,或两者t1并t2失败,myclass将是一个Failure与Exception对t1.如果只是t2失败了,myclass将是一个Failure与Exceptionfor t2.否则,myclass将是一个Success.然后你可以使用recover或者其他方式正常处理它.
您可以对这种情况进行尾递归调用(_, Failure(e)):
@annotation.tailrec
def apply(t1: Try[Any], t2: Try[Any]): Any =
(t1, t2) match {
case (Success(v1), Success(v2)) => new MyClass(v1,v2)
case (Failure(e), _) => println(e.getMessage)
case _ => apply(t2, t1)
}
Run Code Online (Sandbox Code Playgroud)
猫可以让你优雅地做到这一点。对于任何F[_]: Traverse和G[_]: Applicative,它定义了 的等价物Future.sequence:
def sequence(fa: F[G[A]]): G[F[A]]
Run Code Online (Sandbox Code Playgroud)
该库还为 Try 提供了开箱即用的实例。进一步阅读遍历文档。
您可以提取本地方法:
def onFail(e: Throwable) = println(e.getMessage)
(t1,t2) match {
case (Success(v1),Success(v2)) => new MyClass(v1,v2)
case (Failure(e),_) => onFail(e)
case (_,Failure(e)) => onFail(e)
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢它而不是 OlivierBlanvillain 的第一个建议,因为它更容易看出你无法获得无限循环。
| 归档时间: |
|
| 查看次数: |
1547 次 |
| 最近记录: |