Rust: Rust 运算符与表达式:从算术到位运算全掌握

最后更新:2026-08-26

在 Rust 中,几乎所有东西都是表达式——包括 if 和 match。

理解表达式(有返回值)和语句(无返回值)的区别,是写出简洁 Rust 代码的关键。


1. 你将学到


2. 一个收银员的故事

(1) 痛苦:打折计算总是出错

Tom 是一家服装店的店长,他每天要算各种折扣:

"如果有个计算器能自动按正确顺序算就好了……"

(2) Rust 的表达式方案

RUST
fn main() {
    let price: f64 = 299.0;      // 一件衣服 299 元
    let quantity: i32 = 3;        // 买了 3 件
    let is_member: bool = true;   // 是会员

    // 一次表达式算清所有折扣
    let total = (price * quantity as f64)           // 原价
        * if quantity >= 3 { 0.7 } else { 0.9 }    // 数量折扣
        * if is_member { 0.95 } else { 1.0 };      // 会员折扣

    println!("原价: {:.2} 元", price * quantity as f64);
    println!("折后价: {:.2} 元", total);
    println!("节省: {:.2} 元", price * quantity as f64 - total);
}

Rust 的 if 本身是表达式,可以直接返回值。这让打折计算变成一行表达式链,不出错。


3. 运算符一览

100%
graph TB
    A[Rust 运算符] --> B[算术: + - * / %]
    A --> C[比较: == != < > <= >=]
    A --> D[逻辑: && || !]
    A --> E[位运算: & | ^ << >>]
    A --> F[赋值: = += -= *= /=]

(1) 算术运算符

运算符 示例 说明
+ a + b 加法
- a - b 减法
* a * b 乘法
/ a / b 除法(整数截断)
% a % b 取余
- -a 取负(一元)

整数除法会截断5 / 2 = 2(不是 2.5)。要得到浮点结果,需要浮点类型:5.0 / 2.0 = 2.5

(2) 比较运算符

所有比较运算符返回 bool 类型:truefalse

RUST
let a = 10;
let b = 20;
println!("{}", a == b);  // false
println!("{}", a != b);  // true
println!("{}", a < b);   // true

(3) 逻辑运算符

运算符 名称 示例 说明
&& 逻辑与 a && b 两者为真才真(短路)
` ` 逻辑或
! 逻辑非 !a 取反

短路求值&& 左侧为 false 时右侧不执行,|| 左侧为 true 时右侧不执行。这可以用于"先检查再访问"模式。

(4) 位运算符

运算符 名称 示例 说明
& 按位与 a & b 对应位都为 1 才为 1
` ` 按位或 `a
^ 按位异或 a ^ b 对应位不同才为 1
<< 左移 a << n 左移 n 位(相当于乘以 2^n)
>> 右移 a >> n 右移 n 位(相当于除以 2^n)

4. 表达式与语句

(1) 核心区别

概念 定义 示例
表达式 有返回值 5 + 3 返回 8if true { 1 } else { 0 } 返回 1
语句 没有返回值 let x = 5; 不返回值,fn foo() {} 不返回值

Rust 中分号决定表达式还是语句:

RUST
fn main() {
    let y = {
        let x = 3;
        x + 1       // 没有分号——这是表达式,返回 4
    };               // 分号结束 let 语句

    println!("y 的值: {}", y);  // 4
}

(2) 块表达式

{} 包裹的代码块可以是表达式,最后一行不加分号即返回值:

RUST
let result = {
    let a = 2;
    let b = 3;
    a * b           // 不加分号,此块表达式返回 6
};

5. 运算符示例

▶ 示例 1:算术运算与类型(难度 ⭐)

RUST
// ============================================
// 算术运算符演示——注意整数除法截断
// ============================================

fn main() {
    let a = 10;
    let b = 3;

    println!("加法: {} + {} = {}", a, b, a + b);
    println!("减法: {} - {} = {}", a, b, a - b);
    println!("乘法: {} * {} = {}", a, b, a * b);
    println!("整数除法: {} / {} = {} (截断)", a, b, a / b);
    println!("浮点除法: {} / {} = {:.2}", a as f64, b as f64, a as f64 / b as f64);
    println!("取余: {} % {} = {}", a, b, a % b);
}

输出:

TEXT 📖 仅展示
加法: 10 + 3 = 13
减法: 10 - 3 = 7
乘法: 10 * 3 = 30
整数除法: 10 / 3 = 3 (截断)
浮点除法: 10 / 3 = 3.33
取余: 10 % 3 = 1

as 关键字用于类型转换。a as f64 把整数转成浮点后再做除法,得到浮点结果。


▶ 示例 2:逻辑运算短路求值(难度 ⭐⭐)

RUST
// ============================================
// 逻辑运算符的短路求值特性
// ============================================

fn main() {
    let age = 17;
    let has_id = true;

    // && 短路:左侧 false 则右侧不执行
    let can_buy = age >= 18 && has_id;
    println!("可以购买(&&): {}", can_buy);  // false(因为左侧已 false)

    // || 短路:左侧 true 则右侧不执行
    let is_ok = true || (expensive_check());
    println!("(|| 短路,右侧不会执行): {}", is_ok);
}

fn expensive_check() -> bool {
    println!("这个函数不会被执行!");
    true
}

输出:

TEXT 📖 仅展示
可以购买(&&): false
(|| 短路,右侧不会执行): true

短路求值是一个重要的性能优化——把开销小的检查放在左侧,开销大的检查放在右侧,避免不必要的计算。


▶ 示例 3:表达式块返回值(难度 ⭐⭐)

RUST
// ============================================
// 用表达式块实现复杂条件的简洁赋值
// ============================================

fn main() {
    let score = 85;

    let grade = {
        if score >= 90 {
            "A"
        } else if score >= 80 {
            "B"
        } else if score >= 70 {
            "C"
        } else if score >= 60 {
            "D"
        } else {
            "F"
        }
    };  // 注意:整个 if-else 链是一个表达式,用分号结束 let 语句

    println!("分数: {}, 等级: {}", score, grade);

    // 三元运算的替代:用 if 表达式
    let is_pass = if score >= 60 { "passed" } else { "failed" };
    println!("结果: {}", is_pass);
}

输出:

TEXT 📖 仅展示
分数: 85, 等级: B
结果: passed

Rust 没有三元运算符(condition ? a : b),但 if 本身就是表达式,可以达到同样的效果,而且可读性更好。


▶ 示例 4:位运算实战——权限标志与颜色混合(难度 ⭐⭐)

RUST
// ============================================
// 位运算实战:文件权限和 RGB 颜色操作
// ============================================

fn main() {
    let read_perm: u8    = 0b100;   // 4
    let write_perm: u8   = 0b010;   // 2
    let exec_perm: u8    = 0b001;   // 1

    let user_perm = read_perm | write_perm;
    println!("用户权限: {:03b} (读+写)", user_perm);

    let full_perm = read_perm | write_perm | exec_perm;
    println!("完整权限: {:03b} (读+写+执行)", full_perm);

    let can_read = (user_perm & read_perm) != 0;
    let can_exec = (user_perm & exec_perm) != 0;
    println!("用户可读: {},可执行: {}", can_read, can_exec);

    let no_write = user_perm & !write_perm;
    println!("移除写权限: {:03b}", no_write);

    let toggled = user_perm ^ exec_perm;
    println!("切换执行位: {:03b}", toggled);

    let red: u32   = 0xFF0000;
    let green: u32 = 0x00FF00;
    let blue: u32  = 0x0000FF;
    let yellow = red | green;
    let white = red | green | blue;
    println!("\n红色: {:06X}", red);
    println!("黄色 (红|绿): {:06X}", yellow);
    println!("白色 (红|绿|蓝): {:06X}", white);

    let pixel: u32 = 0xFF8040;
    let r = (pixel >> 16) & 0xFF;
    let g = (pixel >> 8)  & 0xFF;
    let b = pixel & 0xFF;
    println!("\n像素 #FF8040 → R={}, G={}, B={}", r, g, b);

    let shift_val: u8 = 1;
    println!("\n1 << 0 = {}", shift_val << 0);
    println!("1 << 1 = {}", shift_val << 1);
    println!("1 << 2 = {}", shift_val << 2);
    println!("1 << 3 = {}", shift_val << 3);
}

输出:

TEXT 📖 仅展示
用户权限: 110 (读+写)
完整权限: 111 (读+写+执行)
用户可读: true,可执行: false
移除写权限: 100
切换执行位: 111

红色: FF0000
黄色 (红|绿): FFFF00
白色 (红|绿|蓝): FFFFFF

像素 #FF8040 → R=255, G=128, B=64

1 << 0 = 1
1 << 1 = 2
1 << 2 = 4
1 << 3 = 8

位运算在系统编程中极为常用:权限管理用 | 合并、& 检查、& ! 移除;颜色用 | 混合、>> + & 提取通道;<< 相当于乘以 2 的幂。


▶ 示例 5:运算符优先级与复合表达式(难度 ⭐⭐⭐)

RUST
// ============================================
// 运算符优先级实战 + 复合赋值运算符
// ============================================

fn main() {
    println!("=== 运算符优先级 ===");
    let a = 2 + 3 * 4;
    println!("2 + 3 * 4 = {} (先乘后加)", a);

    let b = (2 + 3) * 4;
    println!("(2 + 3) * 4 = {} (括号优先)", b);

    let c = 10 - 6 / 2;
    println!("10 - 6 / 2 = {} (先除后减)", c);

    let d = true && false || true;
    println!("true && false || true = {} (&& 优先于 ||)", d);

    let e = true || false && false;
    println!("true || false && false = {} (&& 优先于 ||)", e);

    println!("\n=== 复合赋值运算符 ===");
    let mut score: i32 = 100;
    score += 20;
    println!("score += 20 → {}", score);
    score -= 30;
    println!("score -= 30 → {}", score);
    score *= 2;
    println!("score *= 2 → {}", score);
    score /= 7;
    println!("score /= 7 → {}", score);
    score %= 3;
    println!("score %= 3 → {}", score);

    println!("\n=== 链式比较(用逻辑运算符)===");
    let x = 50;
    let in_range = x >= 0 && x <= 100;
    let out_range = x < 0 || x > 100;
    println!("x={}, 在[0,100]内: {}, 在外: {}", x, in_range, out_range);

    let charlie_score = 75;
    let bob_score = 88;
    let both_passed = charlie_score >= 60 && bob_score >= 60;
    let any_excellent = charlie_score >= 90 || bob_score >= 90;
    println!("两人都及格: {}, 有人优秀: {}", both_passed, any_excellent);
}

输出:

TEXT 📖 仅展示
=== 运算符优先级 ===
2 + 3 * 4 = 14 (先乘后加)
(2 + 3) * 4 = 20 (括号优先)
10 - 6 / 2 = 7 (先除后减)
true && false || true = true (&& 优先于 ||)
true || false && false = true (&& 优先于 ||)

=== 复合赋值运算符 ===
score += 20 → 120
score -= 30 → 90
score *= 2 → 180
score /= 7 → 25
score %= 3 → 1

=== 链式比较(用逻辑运算符)===
x=50, 在[0,100]内: true, 在外: false
两人都及格: true, 有人优秀: false

运算符优先级从高到低:* / %+ - → 比较运算符 → &&||。拿不准时加括号,代码可读性比"简洁"更重要。


❓ 常见问题

Q 5 / 2 在 Rust 里等于多少?
A 等于 2(整数除法截断)。
Q Rust 有没有 ++ 和 -- 运算符?
A 没有。
Q && 和 & 有什么区别?
A && 是逻辑与(短路),& 是按位与(不短路)。
Q 表达式和语句怎么记住?
A 看结尾有没有分号。
Q as 类型转换有什么陷阱?
A as 会静默截断数据,不报错。

📖 小节


📝 作业

  1. 难度 ⭐:写一个程序,用 as 转换把 i32 类型的 52 转成 f64,输出 5 / 2 = 2.5
  2. 难度 ⭐⭐:定义一个变量 x = 5,用表达式块 { x + 1 }y 赋值,同时注意 x 在表达式块外是否还能访问。
  3. 难度 ⭐⭐⭐:用位运算符实现一个函数 fn is_even(n: i32) -> bool,要求用 & 位运算(而不是 %)判断奇偶性。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏