在"main"中使用"Result"时,为什么在"match"



我正在读《铁锈示例》一书。在本例中,删除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>()返回Ok以将number设置为number,则i32。如果返回Err以立即从main返回作为ResultErr(e),则不设置number

这很好,因为number只能是i32,而main确实返回了Result

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

这意味着如果number_str.parse::<i32>()返回Ok以将number设置为number,则i32与之前相同。如果返回Err,则将number设置为Err(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中的每个变量都需要一个单个类型(忽略寿命的方差(。在您的情况下,如果您没有return关键字,那么number的类型是什么?

如果解析成功,则number将是i32。如果失败,它将是一个Err(ParseIntError)。这是不允许的,因此会出现编译错误。

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

类似的情况也适用于其他控制流关键字(例如continuebreak…(,以及保证不会返回的内容,如panic!()(查看Never/!类型以了解更多信息(

最新更新