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

问题描述 投票:20回答:2

在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。)

error-handling rust optional idiomatic rust-result
2个回答
23
投票

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

Result<(), WorkError>意味着你想要完成工作,但它可能会失败。

Option<WorkError>意味着你想得到一个错误,但它可能不存在。

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

我希望Option<WorkError>只能用于像fn get_last_work_error() -> Option<WorkError>这样的情况。


6
投票

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

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

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

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

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

将此与Option<WorkError>Option<()>进行比较

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.