Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

语句与表达式

在 Rust 的设计哲学中,一切皆表达式是一个核心概念。理解语句Statements表达式Expressions的区别,是掌握 Rust 函数返回值、控制流赋值以及函数式编程风格的关键。


一、基本定义

1. 语句 (Statements)

语句是执行某种操作但不返回值的指令。

  • 在 Rust 中,最常见的语句是变量声明 let x = 5;
  • 语句通常以分号 ; 结尾。
  • 注意 :因为语句不返回值,所以你不能把 let 语句赋值给另一个变量(例如 let x = (let y = 5); 会报错)。

2. 表达式 (Expressions)

表达式会计算并产生一个

  • 数学运算(如 5 + 6)、函数调用、宏调用都是表达式。
  • 甚至大括号包裹的代码块 {} 也是表达式。
  • 核心规则 :表达式的结尾 没有分号 。如果你在表达式末尾加上分号,它就会变成一条语句,返回值会变成单元类型 ()

二、块表达式 (Block Expressions)

在 Rust 中,我们可以使用 {} 创建一个作用域,这个作用域本身就是一个表达式,它的值是其中最后一行表达式的值。

fn main() {
    let y = {
        let x = 3;
        x + 1  // 注意:这里没有分号!
    };

    println!("y 的值是: {y}"); // 输出 4
}

深度解析:

如果你在 x + 1 后面加了分号,变成 x + 1;,那么这个块就不再返回 4,而是返回 ()(unit 类型),编译器会因此报错(如果 y 预期是整数类型的话)。


三、函数中的应用:隐式返回

Rust 函数不需要显式写 return 关键字来返回值。只要函数体的最后一行是一个 表达式 (没有分号),该表达式的值就会自动作为函数的返回值。

fn add_one(x: i32) -> i32 {
    x + 1 // 这是一个表达式,隐式返回其结果
}

fn main() {
    let result = add_one(10);
    println!("结果是: {result}");
}

显式 return 与隐式返回的区别:

  • 隐式返回 (不带 return 和分号):Rust 推荐的标准写法,代码更简洁。
  • 显式 return :通常用于函数中途提前退出(提前返回)。
fn check_number(n: i32) -> String {
    if n < 0 {
        return String::from("错误:负数"); // 提前退出
    }
  
    String::from("正常") // 隐式返回
}
fn main() {
    let result = check_number(-10);
    println!("检查结果: {result}");
}

四、常见陷阱:分号的影响

分号在 Rust 中不仅仅是结束符,它是 类型的转换器 。它将一个“有值”的表达式转换成一个“无值”的语句。

示例类别结果/值
5 + 6表达式11
5 + 6;语句()(Unit)
let x = 5;语句无值(报错不能被赋值)
if true { 1 } else { 0 }表达式1

五、综合示例:在一个函数中观察

下面的代码展示了如何在实际逻辑中混合使用语句和表达式:

fn main() {
    let x = 5;

    // 一个复杂的赋值表达式
    let result = if x > 0 {
        let temp = x * 2; // 语句
        temp + 10         // 表达式:整个 if 块的值变为 20
    } else {
        0                 // 表达式
    };

    println!("最终计算结果: {result}");

    // 调用一个只有语句的函数
    print_unit();
}

// 该函数没有返回值,或者说隐式返回 ()
fn print_unit() {
    println!("我执行了一些操作,但我返回的是单元类型 ()");
    // 这里其实隐藏了一个没有分号的 ()
}

六、操作符优先级

在Rust中,一切皆表达式,那么了解表达式的优先级就非常重要了,将Rust的操作符和表达式按优先级由高到低的顺序列了出来,具有相同优先级的操作符按相关性给定的顺序进行优先级计算。

操作符优先级

总结对比

特性语句 (Statements)表达式 (Expressions)
是否有分号 (通常以 ;结尾) (末尾无 ;
是否有返回值 (返回 ()
典型例子let x = 5;x + 5/my_func()
函数末尾不会作为返回值会自动作为返回值