加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用scala.util.Try进行for-understanding时的快速失败

发布时间:2020-12-16 08:54:26 所属栏目:安全 来源:网络整理
导读:我非常喜欢 scala 2.10中的 scala.util.Try,以及它如何与for-comprehension一起使用,可以轻松处理可能出错的多个步骤. 例如,我们可以使用以下代码来确保我们只打印出这两个数字,当且仅当一切都在控制之下并且我们正确地得到了值. def tryA: Try[Int] = {....
我非常喜欢 scala 2.10中的 scala.util.Try,以及它如何与for-comprehension一起使用,可以轻松处理可能出错的多个步骤.

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

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.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>

我们可以看到这里没有任何事情发生,即使tryB是一个例外的失败.我想得到的是抛出异常,如果没有引入带有yield的新Try [Unit]对象,这可能吗?

解决方法

你可以使用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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读