Bri*_*Hsu 8 scala exception try-catch
我非常喜欢scala.util.TryScala 2.10,以及它如何与for-comprehension一起使用可以轻松处理可能出错的多个步骤.
例如,我们可以使用以下代码来确保我们只打印出这两个数字,当且仅当一切都在控制之下并且我们正确地得到了值.
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}
for {
a <- tryA
b <- tryB
} {
println (s"We got:${a+b}")
}
Run Code Online (Sandbox Code Playgroud)
但我担心的一个问题是这个代码实际上忽略了任何异常,这意味着它看起来像下面的try-cactch块:
try {
// .....
} catch {
case _: Exception => // Swallow any exception
}
Run Code Online (Sandbox Code Playgroud)
据我所知,有一种说法认为这种代码是一种难闻的气味,因为没有人会注意到发生了异常.
我想要实现的是仍然使用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
Run Code Online (Sandbox Code Playgroud)
为了使事情更清楚,这是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>
Run Code Online (Sandbox Code Playgroud)
我们可以看到这里没有任何事情发生,即使tryB是Failure例外.我想得到的是抛出异常,如果没有引入新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
Run Code Online (Sandbox Code Playgroud)
我删除了resNN反映的Success(()).
| 归档时间: |
|
| 查看次数: |
5668 次 |
| 最近记录: |