如果成功,从函数返回错误的惯用方法是什么?

Oth*_*ers 28 error-handling idiomatic optional rust rust-result

在Rust中,我认为处理可恢复错误的惯用方法是使用Result.例如,这个功能显然是惯用的:

fn do_work() -> Result<u64, WorkError> {...}
Run Code Online (Sandbox Code Playgroud)

当然,还有一些具有单一,明显的故障状态的功能,因此使用Option类型.一个惯用的例子是这样的:

fn do_work() -> Option<u64>
Run Code Online (Sandbox Code Playgroud)

这一切都在文档中直接解决.但是,我对函数可能失败的情况感到困惑,但在成功时没有任何有意义的值.比较以下两个功能:

fn do_work() -> Option<WorkError>
// vs
fn do_work() -> Result<(), WorkError>
Run Code Online (Sandbox Code Playgroud)

我只是不确定哪一个更惯用,或者更常用于现实世界的Rust代码.我这样的问题的首选资源是Rust书,但我不认为这是在" 错误处理 "部分中解决的.我也没有任何其他Rust文档的运气.

当然,这似乎是相当主观的,但我正在寻找权威的来源,要么说明哪种形式是惯用的,要么说明为什么一种形式优于(或劣等)另一种形式.(我也很好奇这个约定如何与其他大量使用"错误作为值"的语言相比,比如Go和Haskell.)

WiS*_*GaN 28

使用fn do_work() -> Result<(), WorkError>.

Result<(), WorkError> 意味着您希望完成工作,但可能会失败.

Option<WorkError> 意味着您想要收到错误,但可能缺席.

您可能希望完成工作但不要在写入时出错do_work(),因此这Result<(), WorkError>是更好的选择.

我希望Option<WorkError>只能在像这样的情况下使用fn get_last_work_error() -> Option<WorkError>.

  • @Others整个标准库普遍使用`Result <(),_>`当一个可能失败的操作没有返回任何有用的东西时(例如`std :: io`和`std :: fs`的许多函数).这是正确的选择. (4认同)

Pao*_*lla 6

Rust是"相当强烈的类型"(请不要打电话给我如何测量一种语言的强度类型......).我的意思是,在某种意义上,Rust通常会为您提供工具,让类型为您"说话"并记录您的代码,因此使用此功能编写可读代码是不恰当的.

换句话说,你问的问题应该更多"哪种类型最能代表函数对读取签名的人所做的事情?"

因为Result<(), Workerror>你可以直接从文档中看到

结果是表示成功(Ok)或失败(Err)的类型

因此,专门针对您的情况,这意味着如果函数成功(由表示Ok<()>)或者WorkError如果有错误(Err<WorkError>),则函数不会返回任何内容.这是您在问题中描述函数的方式的代码中非常直接的表示.

将此与Option<WorkError>或比较Option<()>

Type Option表示可选值:每个Option都是Some,包含值或None,但不包含

在你的情况下,Option<WorkError>会对读者说"这个函数应该返回一个,WorkError但它可能什么都不返回".您可以记录"什么都不返回"的情况意味着该功能实际上是成功的,但仅从类型来看并不是很明显.

Option<()>说"这个函数不能返回任何内容或者没有任何有意义的返回",如果不WorkError包含其他信息(如错误类型或错误消息),这可能是一个合理的说法,而且实际上只是说"发生了错误" ".在这种情况下,简单bool包含相同的信息...否则,Result您可以返回与错误相关的更多信息.