gpt4 book ai didi

Scala:处理来自 Java 库的异常的最佳方法?

转载 作者:行者123 更新时间:2023-12-03 11:24:12 26 4
gpt4 key购买 nike

假设我正在使用我的 Scala 项目中的 Java 库。该 Java 库会到处抛出异常,但让它们“在 Scala 世界中”传播我感到不舒服,因为无法确定 Scala 方法可以抛出哪些异常(除非通过记录它们)。所以这是我倾向于编写的代码:

def doesNotThrowExceptions(parameter: String): Either[Throwable, T] =
catching(classOf[IOException], classOf[NoSuchAlgorithmException]) either {
// Code calling the Java library
// Code generating a value of type T
}

然后,通常,我会使用 Either.RightProjection.flatMap链接返回 Either[Throwable, ...] 的方法或 Either.RightProjection.map混合返回 Either[Throwable, ...] 的方法和其他方法。或者干脆 Either.foldThrowable 做点什么值(value)。然而,不知何故,这仍然感觉不完全正确。

这是在 Scala 中处理 Java 异常的最“惯用”方式吗?没有更好的办法吗?

最佳答案

我不确定是否有一种最惯用的方法来处理 Java 的异常,因为它们至少会抛出四种不同的情况:

  • 您和库设计者都没有真正预料到会出错的事情出错了。
  • 库设计者希望行之有效的东西没有,你需要知道细节。
  • 你希望的东西没有用,你不需要知道细节。
  • 有时该方法会产生一个值,有时则不会,它通过抛出异常来传达该值。

  • 对于这些案例中的每一个,最佳实践可以说是不同的

    1. 真正的异常(exception)

    Scala 具有功能齐全的异常处理。让意外的异常传播未被发现并没有错,直到您达到可以对此做些什么的水平。将所有可能的异常打包成 Either会浪费很多时间。只需记录您知道您没有处理的内容,并在适当的高级别使用 try/catch(例如 saveEverything 方法可能应该放在 try/catch 块中(或将其内容包装在一个块中),因为无论发生了什么错误,如果保存所有内容失败,您可能想尝试挽救这种情况,而不仅仅是死亡)。

    特别是,您可能想要处理 Error以这种方式只打包 Exception ,并非所有 Throwable s,进入 Either .

    2. 您需要了解的异常(exception)情况

    这就是你所说的情况,你已经就如何处理这些问题给出了一些很好的建议。正如您已经注意到的,您可以使用 catching将异常打包成 Either .然后你也可以

    一种。使用模式匹配,这会让你分开你的 Either更深入:
    doesNotThrowExceptions("par").right.map(transformData) match {
    case Left(ioe: IOException) => /* ... */
    case Left(nsae: NoSuchAlgorithmException) => /* ... */
    case Right(x) => /* ... */
    case Left(e) => throw e // Didn't expect this one...
    }

    湾下变频到 Option记录错误后:
    doesNotThrowExceptions("par").left.map{ e =>
    println("You're not going to like this, but something bad happened:")
    println(e)
    println("Let's see if we can still make this work....")
    }.right.toOption

    C。如果异常是您的流程控制的一个非常重要的部分, Either可能还不够。您可能想要定义自己的 Either - 类似类(class),不仅仅是 LeftRight .或者您可以嵌套 Either 的左侧:
    try { Right(/* java code */) }
    catch {
    case ioe: IOException => Left(Left(ioe))
    case nsae: NoSuchAlgorithmException => Left(Right(nsae))
    }

    d.使用 Scalaz Validation ,这很像 Either但针对异常处理进行了更多定制。

    3. 您只需要知道出现问题的异常(exception)情况,以及

    4. 抛出异常表示无返回值

    尽管它们在概念上是两个不同的类别,但您可以以相同的方式处理它们:
    catching(classOf[IOException], classOf[NoSuchAlgorithmException]) opt { ... }

    获得 Option背部。然后 map , flatMap , 等等..

    关于Scala:处理来自 Java 库的异常的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9291600/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com