返回表达式 return
return 表达式用于函数或者闭包 (closure)中, 从当前函数上下文退出, 返回到函数调用处.
如果函数的返回值为空, 它返回的是 (), 即所谓的 unit struct, 类似于 C 语言中的 void. 比如:
fn do_some() -> () {
...
return;
}
类似于:
void do_some() {
...
return;
}
如果 return obj; 表达式是函数中最后一个表达式, 那么 return 表达式中可以简写为 foo, 看个例子:
fn max_num(a: i32, b: i32) -> i32 {
if a > b {
return a;
} else {
return b;
}
}
通常会被简写成以下形式:
fn max_num(a: i32, b: i32) -> i32 {
if a > b {
a
} else {
b
}
}
return 表达式的优先级
先看一个基于 RustQuiz#20 修改的示例程序, 考虑考虑程序运行的结果是什么样的:
#![allow(unreachable_code)]
#![allow(unused_braces)]
#[rustfmt::skip]
fn return1() {
if (return { println!("1") } ) {
}
}
#[rustfmt::skip]
fn return1_expanded() {
if (return println!("1")) {
}
}
fn return1_simplified() {
println!("1")
}
#[rustfmt::skip]
fn return2() {
if return { println!("2") } {
}
}
#[rustfmt::skip]
fn return2_expanded() {
if return println!("2") {
}
}
fn return3() {
if (return {
println!("3");
}) {}
}
fn main() {
return1();
return1_expanded();
return1_simplified();
return2();
return2_expanded();
return3();
}
其中, return1() 函数的 MIR 代码如下:
fn return1() -> () {
let mut _0: ();
let _1: ();
let mut _2: std::fmt::Arguments<'_>;
let mut _3: &[&str];
let mut _4: &[&str; 1];
bb0: {
_4 = const return1::promoted[0];
_3 = _4 as &[&str] (PointerCoercion(Unsize));
_2 = Arguments::<'_>::new_const(move _3) -> [return: bb1, unwind continue];
}
bb1: {
_1 = _print(move _2) -> [return: bb2, unwind continue];
}
bb2: {
return;
}
}
const return1::promoted[0]: &[&str; 1] = {
let mut _0: &[&str; 1];
let mut _1: [&str; 1];
bb0: {
_1 = [const "1\n"];
_0 = &_1;
return;
}
}
再看一下 return2() 函数的 MIR 代码:
fn return2() -> () {
let mut _0: ();
let _1: ();
let mut _2: std::fmt::Arguments<'_>;
let mut _3: &[&str];
let mut _4: &[&str; 1];
bb0: {
_4 = const return2::promoted[0];
_3 = _4 as &[&str] (PointerCoercion(Unsize));
_2 = Arguments::<'_>::new_const(move _3) -> [return: bb1, unwind continue];
}
bb1: {
_1 = _print(move _2) -> [return: bb2, unwind continue];
}
bb2: {
return;
}
}
const return2::promoted[0]: &[&str; 1] = {
let mut _0: &[&str; 1];
let mut _1: [&str; 1];
bb0: {
_1 = [const "2\n"];
_0 = &_1;
return;
}
}
对比 return2() 的 MIR 代码可以发现, 它与 return1() 的代码是相同的.
从这里我们可以学习到, return 表达式比 if 表达式有更高的优先级, 它优先与后面的表达式结合, 组合成 return 表达式,
并作为 if 表达式的条件 (condition).
如何理解呢? return 有更高的优先级, 它优先与大括号中的语句结合, 所以那个大括号是多余的,
cargo clippy 会给出相应的提示, 就像下图所示: