为什么在 `main` 中使用 `Result` 时 `match` arm 中需要 `return`?

Why is `return` necessary in `match` arm when using `Result` in `main`?

我正在阅读 Rust by Example 书。在此 example 中删除 Err(e) => return Err(e) 中的 return 会导致错误:expected `i32`, found enum `Result`` 。这是为什么?

Err(e) => return Err(e)Err(e) => Err(e)有什么区别?

示例代码如下:

use std::num::ParseIntError;

fn main() -> Result<(), ParseIntError> {
    let number_str = "10";
    let number = match number_str.parse::<i32>() {
        Ok(number)  => number,
        Err(e) => return Err(e),
    };
    println!("{}", number);
    Ok(())
}
    let number = match number_str.parse::<i32>() {
        Ok(number)  => number,
        Err(e) => return Err(e),
    };

这表示如果 number_str.parse::<i32>() return 一个 Oknumber 设置为 number,一个 i32。如果returns一个Err立即returnErr(e),也就是一个Result,从mainnumber不是设置。

没关系,因为 number 只能是 i32main 是 return 和 Result.

    let number = match number_str.parse::<i32>() {
        Ok(number)  => number,
        Err(e) => Err(e),
    };

这表示如果 number_str.parse::<i32>() return 一个 Oknumber 设置为 number,一个 i32,和以前一样。如果returns一个Err设置numberErr(e),这是一个Result.

number 不能同时是 i32Result,所以你会得到一个编译器错误。

match 的所有分支都必须具有“兼容”类型。这要么意味着它们都具有相同的类型:

fn is_some<T>(opt: &Option<T>) -> bool {
  match opt {
    // both arms have type bool
    Some(_) => true,
    None => false,
  }
}

或者某些分支需要以某种方式将控制流从匹配项中引导出去。

要记住的主要规则是 Rust 中的每个变量都需要一个 单一 类型(忽略方差 w.r.t. 生命周期)。在您的情况下,如果您没有 return 关键字,那么 number 的类型是什么?

如果解析成功,number 将是一个 i32。如果失败,它将是 Err(ParseIntError)。这是不允许的,所以你会得到一个编译错误。

但是,如果您 return Err(e)number 将始终是 i32(因为 return 阻止了函数 运行 的其余部分,因此 number 不需要类型)。

类似的事情适用于其他 control-flow 关键字(例如 continuebreak、...),以及保证不会 return 的事情,例如 panic!()(查找 Never/! 类型以获取更多信息)