scala - 在 scala 中正确使用 Either、Try 和 Exceptions/ControlThrowable
问题描述
在我的 scala 代码(库和应用程序)中,我目前混合使用Option
and Try
,只要两者中的任何一个感觉更合适。
我倾向于实现“doSomething”- 方法,这些方法可以成功返回值或失败Try
。也就是说,它们可以包含throw的代码,或者,当我“手动”检测错误时,我人为地创建 aThrowable
并返回 a Failure
。因此,这些方法的返回值是 a Try[ReturnType]
。
现在我读到创建异常有点不太理想,因为它创建了一个堆栈跟踪(因此很慢),我什至不需要它。我还看到了使用 的子类的示例ControlThrowable
,它们不会创建堆栈跟踪,但是它们也没有消息,Try
当然也不会捕获它。
现在我的具体问题是,当我想要执行运行时错误处理/方法返回值时,我是否应该普遍赞成,并且只Either
在我实际需要捕获某些东西的情况下使用(例如第三方代码)?
这样我就不必创建笨拙的 s,而只使用例如字符串来处理错误。Try
Try
Throwable
Left
所以基本上:
Option
: 每天都在使用一些有价值或没有价值的东西Try
: 在方法中捕获异常,但不用作返回值Either
:通用返回值,包含错误(字符串)或成功值
这个概念会奏效吗,还是有更可行/更常见的方法?
解决方案
正如特拉维斯布朗在评论中所说,没有真正的惯例,这在很大程度上是一种文化现象。为了保持代码的可读性,一致性是这里最重要的事情。我见过代码库:
- 使用选项表示“
None
成功且任何Some(...)
包含错误消息” - 使用 Try 以返回包含空字符串的 Success 或包含错误消息的 Failure
- 使用 Either 错误的方式(即
Either[?, Throwable]
)
显然,这些都不是好的做法,但只要你坚持不懈,这并不重要。我个人在娱乐和工作中使用的惯例是:
Option
用于丢失值的有效时间(例如,使用 playframework 解析 JSON 时)。Try
当尝试做一些可能失败的事情时(除非它在未来,在这种情况下我只使用.recover
),我关心匹配异常的类型,但也想要成功的结果(如果可用)。Either
当我不想在我的“失败”情况下返回异常/可抛出(虽然老实说这很少见)。
无论我使用上述哪一种,我个人认为最好尽可能长时间地把它包起来。这会阻止不必要的 Throwables 在您的代码中被抛出(哈哈),并使调试更容易,因为没有任何隐藏getOrElse
行返回默认值(这在大型代码库中会变得非常烦人)。
推荐阅读
- python - 无法使用类的实例打印类列表属性
- javascript - 为什么 Async 总是返回一个 Promise?
- javascript - 如何从自定义“redirect-https”中间件重定向中删除端口号
- java - 我面临 500 内部服务器错误:拒绝访问文件
- python - 如何重新排列子图,使一个在另一个之下?
- plsql - PLSQL 过程将数据从多个表加载到维度表中
- c++ - 函数总是返回 1
- sql - 可以加快这个查询?
- javascript - 如何在 UWP 安装的应用程序中添加一些源代码?
- excel - 从 A 列中的字符串(即段落)中删除特定的词性和标点符号,然后在 B 列中输入结果