使用结果有什么好处?

道格

我不明白为什么Result在Rust中存在。我可以看到如何Option有用,但是使用Result似乎不必要地使代码复杂化。

考虑以下示例:

#[derive(PartialEq, Eq, Debug)]
enum MyErr {
    None,
    FailOne,
}

fn returns_tuple() -> (u8, MyErr) {
    // (1, None) // <-- Success path
    (0, MyErr::FailOne)
}

fn returns_result() -> Result<u8, MyErr> {
    // Ok(1) // <-- Success path
    Err(MyErr::FailOne)
}

#[test]
fn test_check_return_values() {
    let x = returns_result();
    if x.is_ok() {
        println!("result: Is OK: {}", x.unwrap()); // <-- Must use unwrap
    } else {
        match x.err().unwrap() { // <-- Again, unwrapping
            MyErr::None => {}, // Required for match
            MyErr::FailOne => println!("result: Failed One"),
        }
    }
}

#[test]
fn test_check_return_values_2() {
    let (y, err) = returns_tuple();
    match err {
        MyErr::None => println!("tuple: Is OK: {}", y),
        MyErr::FailOne => println!("tuple: Failed one"),
    }
}

我唯一看到的是,它可以稍微增加函数编写器的便利性,因为您可以简单地调用Ok()Err()返回结果。

我见过有人在说它,以便您可以使用条件,但这完全不是事实。您可以使用元组完美地使用条件。注:“条件”是Rust的功能,在1.0之前已被删除

我也看到有些人说Result是更好的性能是返回一个元组,但是Result 一个元组,所以我看不出这可怎么是这种情况。

克里斯·摩根

让我们考虑一下的定义Result

/// `Result` is a type that represents either success (`Ok`) or failure
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[must_use]
pub enum Result<T, E> {
    /// Contains the success value
    Ok(T),

    /// Contains the error value
    Err(E)
}

精炼成重要的东西,那就是enum Result<T, E> { Ok(T), Err(E) }

那不是元组(T, E); 相反,它是T(OK)一个E(错误)。

如果你使用一个元组(T, E),则必须同时定义T E对您而言returns_tuple,这意味着将0定义为魔术值,并为您的MyErr枚举添加新的变体NoneNone不是错误;因此,在语义上进行建模是不明智的。然后,由于需要详尽的匹配,它还会传播到其他地方。

当您处理更复杂的类型时,定义虚拟值可能不太可行或更昂贵。概括地说,具有虚拟值不是一个好的计划。您很有可能实际上会尝试使用它们。

Rust具有良好的类型系统,可让您避免此类问题。

在我看来,您似乎错过了Rust的匹配能力;实际上,从枚举中获取值的唯一方法是模式匹配。结果,事情喜欢Result.ok()Result.err()并且Option.unwrap()在模式匹配方面实现。

现在,让我们以更好地显示Rust的方式编写示例。

#[derive(PartialEq, Eq, Debug)]
enum MyErr {
    // Now we don't need that phoney None variant.
    FailOne,
}

fn returns_result() -> Result<u8, MyErr> {
    Err(MyErr::FailOne)
}

#[test]
fn test_check_return_values() {
    match returns_result() {
        Ok(num) => println!("result: Is OK: {}", num),
        Err(MyErr::FailOne) => println!("result: Failed One"),
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章