scala - 将 for-comprehension 与 scala.util.Try 一起使用时快速失败

标签 scala exception try-catch

我真的很喜欢scala.util.Try在 Scala 2.10 中,以及它如何与 for-comprehension 一起工作,可以处理容易出错的多个步骤。

例如,我们可以使用下面的代码来确保我们只打印出这两个数字,当且仅当一切都在控制之下并且我们正确地获得了值(value)。

def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}

for {
  a <- tryA
  b <- tryB
} { 
  println (s"We got:${a+b}")
}

但我担心的一个问题是这段代码实际上忽略了任何异常,这意味着它看起来像下面的 try-cactch 块:
try {
  // .....
} catch {
  case _: Exception => // Swallow any exception
}

据我所知,有一种说法是这种代码很臭,因为没有人会注意到发生了异常。

我想实现的是仍然使用 for以确保 println只在一切正常的情况下才执行,但是如果任何步骤出现异常,它就会炸毁并直接抛出异常。

目前这是我如何做到这一点,但它似乎不太优雅,因为它引入了一个新的 Try[Unit]对象,所以我想知道如何使这段代码更好?

例如,是否可以去掉 result变量和 result.get语句,但仍然抛出异常?
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}

val result = for {
  a <- tryA
  b <- tryB
} yield { 
  println (s"We got:${a+b}")
}
result.get

更新

为了让事情更清楚,这是这个问题中第一个代码的 Scala REPL 的结果。
scala> def tryA: Try[Int] = Success(1)
tryA: scala.util.Try[Int]

scala> def tryB: Try[Int] = Failure(new Exception("error"))
tryB: scala.util.Try[Int]

scala> for {
     |   a <- tryA
     |   b <- tryB
     | } { 
     |   println (s"We got:${a+b}")
     | }

scala> 

我们可以看到这里什么也没发生,甚至 tryBFailure除了异常(exception)。我想得到的是抛出异常,并且没有引入新的 Try[Unit]对象 yield , 这可能吗?

最佳答案

您可以使用 recover :

import scala.util.Try

def tryEven = Try { val i = (math.random * 1000).toInt; if (i % 2 != 0) throw new Exception("odd") else i }

def tryEvenOrNeg1 = Try { val i = (math.random * 1000).toInt; if (i % 2 != 0) throw new Exception("odd") else i } recover { case exx: Exception => -1 }

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
res1: scala.util.Try[Unit] = Failure(java.lang.Exception: odd)

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
res2: scala.util.Try[Unit] = Failure(java.lang.Exception: odd)

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
res3: scala.util.Try[Unit] = Failure(java.lang.Exception: odd)

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
Got 542, -1

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
res5: scala.util.Try[Unit] = Failure(java.lang.Exception: odd)

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
res6: scala.util.Try[Unit] = Failure(java.lang.Exception: odd)

scala> for (a <- tryEven; b <- tryEvenOrNeg1) yield println(s"Got $a, $b")
Got 692, 750

我删除了 resNN反射(reflect)了Success(()) .

关于scala - 将 for-comprehension 与 scala.util.Try 一起使用时快速失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15015495/

相关文章:

scala - 如何忽略 Scala 中的 "-Ywarn-unused"警告?

scala - 如何使用 Play 2.1/Scala 设置 cookie?

scala - 为什么 Scala 案例类字段不反射(reflect)为公共(public)的?

java - 局部变量变为空(Android)

c# - 如何以编程方式修复非规范 ACL?

javascript - 抛出预期错误 : RangeError: Invalid array length

scala - 使用带有任一 T 的 scala.concurrent.Future 时缺少 Functor 和 Monad 实例

c# - HttpWebResponse 始终为空

java - 数据库try-catch block 代码不执行

php - 获取特定功能的错误