在scala中正确使用Either,Try和Exception / ControlThrowable

时间:2019-02-13 07:56:53

标签: scala error-handling exception-handling try-catch either

在我的Scala代码(库和应用程序)中,无论何时,无论哪种情况,我都同时使用OptionTry的组合。

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

现在我读到创建异常在某种程度上不是最优的,因为它创建了堆栈跟踪(因此很慢),我什至不需要。我还看到了使用ControlThrowable子类的示例,这些示例没有创建堆栈跟踪,但是它们也没有消息,并且Try当然也不会捕获它。

现在我的具体问题是,当我想执行运行时错误处理/方法返回值时,我一般应该优先选择Either而不是Try,并且仅在以下情况下使用Try吗?我实际上需要抓住的东西(例如第三方代码)吗?
这样,我就不必创建笨拙的Throwable,而只需使用例如Left中的字符串以查找错误。

所以基本上:

  • Option:日常使用的东西是否具有价值
  • Try:在方法内捕获异常,但不用作返回值
  • Either:通用返回值,包含错误(字符串)或成功值

这个概念行得通吗,还是有一种更可行/更通用的方法?

1 个答案:

答案 0 :(得分:4)

正如Travis Brown在评论中所指出的,没有 real 约定,这在很大程度上是一种文化上的事情。为了保持代码的可读性,一致性是这里最重要的事情。我看过以下代码库:

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

显然,这不是一个好习惯,但是只要您始终如一,这实际上就没有关系。我个人在娱乐和工作中都使用的约定是:

  • Option ,用于确定何时有效的值缺失(例如,使用playframework解析JSON时)。
  • Try ,尝试做可能会失败的事情(除非是在Future中,在这种情况下,我只使用.recover),在这里我关心匹配类型例外,但也希望获得成功的结果。
  • Either ,当我不想在“ fail”情况下返回Exception / Throwable时(虽然说实话,这种情况很少见)。

无论使用哪种方法,我个人都认为最好将其尽可能长时间地包裹起来。这样可以避免在代码中不必要地抛出(haha)的Throwables,并使调试变得更加容易,因为没有隐藏的getOrElse行返回默认值(这在大型代码库中会非常令人讨厌)。