Rust 基础语法
📚 Rust 课程系列
Rust 是一门注重内存安全、性能和并发性的系统编程语言。本篇是《Rust 课程》系列的第一篇,从最基础的变量与常量、数据类型、Range 语法到控制流,带你建立对 Rust 语法骨架的初步认识。后续章节将在所有权、类型系统、并发等方向逐步深入。
变量与常量
| 声明方式 | 可变性 | 类型标注 | 作用域 | 典型用途 |
|---|---|---|---|---|
let x = 5; | 不可变(默认) | 可推断 | 块级 | 一般绑定 |
let mut y = 10; | 可变 | 可推断 | 块级 | 需要修改的值 |
const MAX: u32 = 100; | 不可变 | 必须标注 | 可全局 | 编译期常量 |
static G: &str = "hi"; | 不可变(默认) | 必须标注 | 全局 | 静态生命周期值 |
💡 提示:Rust 变量默认不可变——这是与 C++/Go/Java 最大的区别之一。不可变意味着编译器可以做出更多优化,也从根本上杜绝了"意外修改"类 bug。需要修改时显式写
mut,让意图一目了然。
遮蔽(Shadowing)
1 | |
🔄 对比:遮蔽 ≠ 可变赋值。遮蔽创建新绑定(可改变类型),
mut修改现有绑定(类型固定)。C++ 中同名变量在同级作用域会报错,Rust 则允许遮蔽。⚠️ 注意:遮蔽常用于值转换链(如
let s = s.trim();),但过度使用会降低可读性。同一块内遮蔽超过 2-3 次时应考虑换用更有意义的变量名。
常量与静态变量
1 | |
⚠️ 注意:
static mut是 unsafe 的——多线程并发访问会导致数据竞争。需要全局可变状态时,使用Atomic*类型或Mutex封装,也可用once_cell::sync::Lazy做延迟初始化。
类型别名与字面量后缀
1 | |
数据类型
标量类型速查
| 类别 | 类型 | 备注 |
|---|---|---|
| 有符号整数 | i8 i16 i32 i64 i128 | 默认推断为 i32 |
| 无符号整数 | u8 u16 u32 u64 u128 | 字节操作常用 u8 |
| 架构相关 | isize / usize | 与指针同宽,索引/长度用 usize |
| 浮点数 | f32 f64 | 默认推断为 f64 |
| 布尔 | bool | true / false,占 1 字节 |
| 字符 | char | Unicode 标量值,占 4 字节 |
💡 提示:
char是 Unicode 标量值(4 字节),不是 C 的 1 字节char。'😊'是合法的char,但字符串内部是 UTF-8 编码,一个 Unicode 字符可能占 1-4 字节——按字节切片可能截断字符。
复合类型
1 | |
🔄 对比:切片
&[T]/&str类似 Go 的 slice header(指针+长度),但不包含容量信息。Rust 切片是纯"视图",不能直接 append。⚠️ 注意:处理 UTF-8 字符串时不要盲目按字节切片(
&s[0..n]),可能截断多字节字符。使用char迭代或s.get(..n)做安全检查。
💡 提示:函数参数优先接受
&[T]或&str而非&Vec<T>或&String——切片更通用,可接收数组、Vec 的引用,避免拷贝。空切片&[]合法,可用于表示"无数据"而无需Option。数组 vs Vec 的选择:长度固定且小用数组(栈分配,零开销),需要动态增长用Vec(考虑with_capacity减少重分配)。
字符串与类型转换
1 | |
⚠️ 注意:
as转换在数值截断时静默发生(如300i32 as u8→44)。安全转换请用try_into()或From/Intotrait。
Range(范围)语法
Range 是 Rust 中用于表示序列范围的重要语法,广泛应用于循环迭代、切片操作和模式匹配中。
基本语法
1 | |
切片中的 Range
1 | |
Range 类型
| 语法 | 类型 | 说明 |
|---|---|---|
start..end | Range<T> | 半开区间 |
start..=end | RangeInclusive<T> | 闭区间 |
start.. | RangeFrom<T> | 从 start 到无限 |
..end | RangeTo<T> | 从起点到 end |
..=end | RangeToInclusive<T> | 从起点到 end(包含) |
.. | RangeFull | 全范围 |
1 | |
Range 的迭代与方法
1 | |
Range 在模式匹配中的应用
1 | |
⚠️ 注意:切片越界会 panic,用
get()安全访问:arr.get(1..5)返回Option。半开区间start >= end时 range 为空,循环体不执行。浮点数 range 只有闭区间..=可迭代,但不推荐(精度问题)。
Range 与切片语法(进阶)
🔬 进阶:Range 类型实现了
SliceIndextrait 的类型都可以用作[]索引参数——Range 类型正是如此。自定义类型只要实现SliceIndex,也能用于切片索引,这是 Rust 索引语法可扩展性的基础。
控制流
条件表达式
1 | |
💡 提示:条件必须是
bool,Rust 不会像 C/C++ 那样将整数隐式转为布尔值。if 1 { }是编译错误。
循环
1 | |
💡 提示:优先使用
for+ 迭代器,它比while索引更安全(不会越界)且更符合 Rust 惯例。loop+break返回值适合复杂退出条件且需返回计算结果的场景。
⚠️ 注意:迭代方式的选择影响所有权——
iter()借用、iter_mut()可变借用、into_iter()消费所有权。选错会导致编译错误,详见所有权、借用与生命周期。
标签循环
1 | |
🔄 对比:Rust 的标签语法
'label:类似 Go 的label:,但 Rust 标签只能与break/continue配合使用,不能像 Go 那样goto。
模式匹配在控制流中的应用
1 | |
💡 提示:
match是 Rust 最强大的控制流构造,支持解构、守卫、范围模式等。完整的模式匹配详解见结构体、枚举与模式匹配。

