Rust语句和表达式概念

1. 基本定义

语言 语句 (Statement) 表达式 (Expression)
C/C++ 有副作用或控制流程的构造,大多数语句不产生值(如 ifwhile、赋值、表达式语句) 总是计算出一个值(如 1+2func()
Rust 只做事情、不产生值的构造(目前只有两种:声明语句和表达式语句) 几乎所有构造都产生值,是 Rust 的核心

2. 与C/C++关键区别

C/C++(控制流是语句,不返回值)

int x;
if (condition)
    x = 1;
else
    x = 2;                  // if 是语句,必须单独赋值

int y = std::max(a, b);     // 只能用函数或三元运算符获得值

Rust(if、match、块 等都是表达式,有返回值)

let x = if condition {
    1
} else {
    2
};                          // if 直接产生值,无需额外赋值!

let y = std::cmp::max(a, b);

其他常见rust表达式

  • 块表达式
let x = {
    let temp = 10;
    temp + 5        // 最后一行没有分号,表示返回值
};                  // x = 15
  • match 表达式
let result = match option {
    Some(v) => v,
    None    => 0,
};
  • loop、while、for 也可以产生值(使用 break 返回值)
let result = loop {
    if condition {
        break 42;   // loop 返回 42
    }
};

3. 分号的意义不同

语言 分号的作用
C/C++ 结束一个语句,几乎所有语句都需要分号
Rust 改变表达式行为:加上分号表示丢弃返回值,转为语句
let x = 5;                      // 表达式 5,加上分号 → 变成语句,返回 ()

{
    1 + 2                       // 不加分号 → 块表达式返回 3
};                              // 加分号 → 返回 (),块变成语句

let y = {
    let a = 10;
    a + 1                       // 没有分号 → 返回 11
};
println!("{}", y);              // 输出 11

这就是为什么 Rust 代码最后一行常常不写分号:因为你希望它返回值。

4. 赋值在 Rust 中不是表达式

C/C++:赋值是表达式,有返回值(赋的值)

int a = 0;
int b = (a = 5);    // b = 5,且 a 也被改为 5
while ((ch = getchar()) != EOF) { ... }

Rust:赋值返回 ()(单元类型,无值)

let a = 0;
let b = (a = 5);    // 编译错误!不能把 () 赋值给 b

即rust中a = b = c = 8不合规

5.总结对比

特性 C/C++ Rust
if / match 是否有值 否(语句) 是(表达式)
代码块是否有值 否(复合语句) 是(块表达式,最后表达式返回值)
分号作用 结束语句 丢弃值,把表达式变成语句
赋值是否是表达式 是(返回被赋的值) 否(返回 ())
函数最后 return 可省略 不可(除构造函数等特殊情况) 可以(最后表达式返回值)

同时,C# 8.0之后的版本也引入了SWITCH表达式

string result = day switch
{
    0 => "Sunday",
    1 => "Monday",
    2 => "Tuesday",
    _ => "Unknown"    // _ 表示 default
};

Console.WriteLine(result);   // 一句搞定

评论