在 scala 中正确使用 Either、Try 和 Exceptions/ControlThrowable

Correct usage of Either, Try and Exceptions/ControlThrowable in scala

在我的 Scala 代码(库和应用程序)中,我目前混合使用 OptionTry,只要两者中的任何一个感觉更合适。

我倾向于实施 "doSomething" 方法,这些方法可能会以 return 值成功或以 Try 失败。也就是说,它们可以包含 throw 的代码,或者,当我检测到错误 "by hand" 时,我人为地创建了一个 Throwable 和 return 一个 Failure。因此,这些方法的 return 值为 Try[ReturnType]

现在我读到创建异常有点次优,因为它创建了一个堆栈跟踪(因此很慢),我什至不需要。我还看到了使用 ControlThrowable 的子类的示例,它们不会创建堆栈跟踪,但是它们也没有消息,Try 当然不会捕捉到它。

现在我的具体问题是,当我想进行运行时错误处理/方法 return 值时,我是否应该普遍支持 Either 而不是 Try,并使用 Try 仅在我实际需要 catch 某些东西(例如第三方代码)的情况下?
这样我就不必创建笨拙的 Throwables,而是只使用例如Left 中的字符串错误。

所以基本上:

这个概念是否可行,或者是否有更 viable/common 的方法?

正如 在评论中所述,没有 真正的 惯例,这在很大程度上是一种文化。为了保持代码的可读性,一致性是最重要的事情。我见过代码库:

  • 使用选项表示“None 成功并且任何 Some(...) 包含错误消息”
  • 使用 Try 以 return 包含空字符串的 Success 或包含错误消息的 Failure
  • 错误地使用 Either(即 Either[?, Throwable]

显然这些都不是好的做法,但只要您始终如一,真的 并不重要。我个人在娱乐和工作中使用的约定是:

  • Option 表示当缺失值有效时(例如,使用 playframework 解析 JSON 时)。
  • Try 当尝试做一些可能会失败的事情时(除非它在 ​​Future 中,在这种情况下我只使用 .recover),我在哪里关心匹配异常的类型,但也希望在可用的情况下获得成功的结果。
  • Either 当我不想 return 一个 Exception/Throwable 在我的 "fail" 案例中(虽然是老实说,这很少见。

无论我使用以上哪一种,我个人认为最好将其包装起来尽可能长时间。这会阻止在您的代码中抛出不必要的 Throwables (haha),并使调试更容易,因为没有任何隐藏的 getOrElse 行 returning 默认值 (这在大型代码库中会变得非常烦人。