期权类型和提前回报.is_none() 时返回错误 [英] Option types and early returns. return an Error when is_none()

查看:36
本文介绍了期权类型和提前回报.is_none() 时返回错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用匹配(如在 bar 中)似乎是一种常见的方法..

Using match (like in bar) seems to be a common approach..

#[derive(Debug)]
pub enum MyErrors {
    SomeError,
}

fn foo(x: Option<u64>) -> Result<u64, MyErrors> {
    if x.is_none() {
      return Err(MyErrors::SomeError);
    } 

    // .. some long code where more options
    // are checked and matched 
    // The ok here is just so the code is simple and compiles
    Ok(x.unwrap() * 2)
}

fn bar(x: Option<u64>) -> Result<u64, MyErrors> {
    match x {
        None => {
            return Err(MyErrors::SomeError)?;
        }
        Some(v) => {
           // .. some long code where more options
           // are checked and matched 
           // The ok here is just so the code is simple and compiles
           Ok(x.unwrap() * 2)
        }
    }
}


fn main() {
    foo(Some(1));
    bar(Some(2));
}

然而,提前返回(例如在 foo 中)显着减少了代码的嵌套程度.如果必须多次解包选项或返回错误,则 bar 之类的代码会变得非常嵌套...

However, early returns (such as in foo) significantly reduce how nested the code looks like. If there are multiple times when an option has to be unwrapped or an error returned, code like bar gets very nested...

在空选项的情况下提前返回错误的推荐做法是什么?

What is the recommended practice for early returning an error in the case of empty options?

推荐答案

如果由于内部逻辑复杂而不需要更长的方法链,仍然有一些可读的、低缩进的选项.

If a longer method chain is undesirable due to complex logic inside, there are still a few readable, low-indent options.

我们可以将 Option 转换为带有所需错误的 Result,并立即使用 ? 运算符解开它.此解决方案可能提供尽可能少的缩进,并且可以轻松用于解开"多个 Option.

We can convert an Option to a Result with a desired error, and immediately unwrap it with the ? operator. This solution probably provides the least indent possible, and can be easily used to "unwrap" multiple Options.

fn bar1(x: Option<u64>) -> Result<u64, MyErrors> {
    let x = x.ok_or(MyErrors::SomeError)?;
    // A lot of stuff going on.
    Ok(x * 2)
}

这将评估 ok_or 内部的错误,而不管它是否会被实际使用.如果这个计算很昂贵,那么延迟产生错误的 ok_or_else 将更有效(相关问题).

This will evaluate the error inside ok_or regardless of whether or not it will actually be used. If this computation is expensive, ok_or_else, which produces the error lazily, will be more efficient (related question).

如果嵌套,此解决方案仍会导致代码阶梯,但如果 else 分支逻辑涉及更多,则可能更合适.

This solution can still lead to a staircase of code if nested, but may be more appropriate if the else branch logic is more involved.

fn bar2(x: Option<u64>) -> Result<u64, MyErrors> {
    if let Some(x) = x {
        // Lot of stuff here as well.
        Ok(x * 2)
    } else {
        Err(MyErrors::SomeError)
    }
}

这篇关于期权类型和提前回报.is_none() 时返回错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆