首页 > 解决方案 > 在 scala 中正确使用 Either、Try 和 Exceptions/ControlThrowable

问题描述

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

我倾向于实现“doSomething”- 方法,这些方法可以成功返回值或失败Try。也就是说,它们可以包含throw的代码,或者,当我“手动”检测错误时,我人为地创建 aThrowable并返回 a Failure。因此,这些方法的返回值是 a Try[ReturnType]

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

现在我的具体问题是,当我想要执行运行时错误处理/方法返回值时,我是否应该普遍赞成,并且只Either在我实际需要捕获某些东西的情况下使用(例如第三方代码)? 这样我就不必创建笨拙的 s,而只使用例如字符串来处理错误。TryTry
ThrowableLeft

所以基本上:

这个概念会奏效吗,还是有更可行/更常见的方法?

标签: scalaerror-handlingexception-handlingtry-catcheither

解决方案


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

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

显然,这些都不是好的做法,但只要你坚持不懈,这并不重要。我个人在娱乐和工作中使用的惯例是:

  • Option用于丢失值的有效时间(例如,使用 playframework 解析 JSON 时)。
  • Try当尝试做一些可能失败的事情时(除非它在未来,在这种情况下我只使用.recover),我关心匹配异常的类型,但也想要成功的结果(如果可用)。
  • Either当我不想在我的“失败”情况下返回异常/可抛出(虽然老实说这很少见)。

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


推荐阅读