在 scala 中正确使用 Either、Try 和 Exceptions/ControlThrowable
Correct usage of Either, Try and Exceptions/ControlThrowable in scala
在我的 Scala 代码(库和应用程序)中,我目前混合使用 Option
和 Try
,只要两者中的任何一个感觉更合适。
我倾向于实施 "doSomething" 方法,这些方法可能会以 return 值成功或以 Try
失败。也就是说,它们可以包含 throw 的代码,或者,当我检测到错误 "by hand" 时,我人为地创建了一个 Throwable
和 return 一个 Failure
。因此,这些方法的 return 值为 Try[ReturnType]
。
现在我读到创建异常有点次优,因为它创建了一个堆栈跟踪(因此很慢),我什至不需要。我还看到了使用 ControlThrowable
的子类的示例,它们不会创建堆栈跟踪,但是它们也没有消息,Try
当然不会捕捉到它。
现在我的具体问题是,当我想进行运行时错误处理/方法 return 值时,我是否应该普遍支持 Either
而不是 Try
,并使用 Try
仅在我实际需要 catch 某些东西(例如第三方代码)的情况下?
这样我就不必创建笨拙的 Throwable
s,而是只使用例如Left
中的字符串错误。
所以基本上:
Option
: 每天使用一些有价值或没有价值的东西
Try
:捕获方法内的异常,但不作为return值
Either
:通用return值,包含错误(字符串)或成功值
这个概念是否可行,或者是否有更 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 默认值 (这在大型代码库中会变得非常烦人。
在我的 Scala 代码(库和应用程序)中,我目前混合使用 Option
和 Try
,只要两者中的任何一个感觉更合适。
我倾向于实施 "doSomething" 方法,这些方法可能会以 return 值成功或以 Try
失败。也就是说,它们可以包含 throw 的代码,或者,当我检测到错误 "by hand" 时,我人为地创建了一个 Throwable
和 return 一个 Failure
。因此,这些方法的 return 值为 Try[ReturnType]
。
现在我读到创建异常有点次优,因为它创建了一个堆栈跟踪(因此很慢),我什至不需要。我还看到了使用 ControlThrowable
的子类的示例,它们不会创建堆栈跟踪,但是它们也没有消息,Try
当然不会捕捉到它。
现在我的具体问题是,当我想进行运行时错误处理/方法 return 值时,我是否应该普遍支持 Either
而不是 Try
,并使用 Try
仅在我实际需要 catch 某些东西(例如第三方代码)的情况下?
这样我就不必创建笨拙的 Throwable
s,而是只使用例如Left
中的字符串错误。
所以基本上:
Option
: 每天使用一些有价值或没有价值的东西Try
:捕获方法内的异常,但不作为return值Either
:通用return值,包含错误(字符串)或成功值
这个概念是否可行,或者是否有更 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 默认值 (这在大型代码库中会变得非常烦人。