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

时间:2016-04-27 00:14:35

标签: error-handling rust optional idiomatic rust-result

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

fn do_work() -> Result<u64, WorkError> {...}

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

fn do_work() -> Option<u64>

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

fn do_work() -> Option<WorkError>
// vs
fn do_work() -> Result<(), WorkError>

我只是不确定哪一个更惯用,或者更常用于现实世界的Rust代码。对于像这样的问题,我的首选资源是Rust书,但我不认为这在“Error Handling”部分中得到了解决。我也没有任何其他Rust文档的运气。

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

2 个答案:

答案 0 :(得分:21)

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

Result<(), WorkError>表示您希望完成工作,但可能会失败。

Option<WorkError>表示您想要收到错误,但可能缺席。

您可能希望完成工作,但在撰写do_work()时不会收到错误,因此Result<(), WorkError>是更好的选择。

我希望Option<WorkError>仅用于fn get_last_work_error() -> Option<WorkError>等个案。

答案 1 :(得分:6)

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

换句话说,您提出的问题应该更多&#34;哪种类型最能代表该功能对读取其签名的任何人的影响?&#34;

对于Result<(), Workerror>,您可以直接看到from the docs

  

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

的类型

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

将其与Err<WorkError>Option<WorkError>

进行比较
  

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

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

WorkError说&#34;这个函数不返回任何内容或没有有意义的返回&#34;,如果Option<()>不包含其他信息(如错误类型),这是合理的说法或者错误信息)它实际上只是一种说法&#34;发生错误的方式&#34;。在这种情况下,简单的WorkError包含相同的信息......否则bool会让您返回与错误相关的更多信息。