为什么在 `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 一个 Ok
将 number
设置为 number
,一个 i32。如果returns一个Err
立即returnErr(e)
,也就是一个Result
,从main
,number
不是设置。
没关系,因为 number
只能是 i32
而 main
是 return 和 Result
.
let number = match number_str.parse::<i32>() {
Ok(number) => number,
Err(e) => Err(e),
};
这表示如果 number_str.parse::<i32>()
return 一个 Ok
将 number
设置为 number
,一个 i32,和以前一样。如果returns一个Err
设置number
到Err(e)
,这是一个Result
.
number
不能同时是 i32
和 Result
,所以你会得到一个编译器错误。
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 关键字(例如 continue
、break
、...),以及保证不会 return 的事情,例如 panic!()
(查找 Never
/!
类型以获取更多信息)
我正在阅读 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 一个 Ok
将 number
设置为 number
,一个 i32。如果returns一个Err
立即returnErr(e)
,也就是一个Result
,从main
,number
不是设置。
没关系,因为 number
只能是 i32
而 main
是 return 和 Result
.
let number = match number_str.parse::<i32>() {
Ok(number) => number,
Err(e) => Err(e),
};
这表示如果 number_str.parse::<i32>()
return 一个 Ok
将 number
设置为 number
,一个 i32,和以前一样。如果returns一个Err
设置number
到Err(e)
,这是一个Result
.
number
不能同时是 i32
和 Result
,所以你会得到一个编译器错误。
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 关键字(例如 continue
、break
、...),以及保证不会 return 的事情,例如 panic!()
(查找 Never
/!
类型以获取更多信息)