1. Rust 语法速查手册:从入门到实战
作为一名从C++转战Rust的系统程序员,我深刻理解学习新语言时对语法速查的迫切需求。Rust以其独特的所有权系统和零成本抽象闻名,但这也意味着它的语法结构与常见语言存在显著差异。这份手册不同于官方文档的全面铺陈,而是聚焦实际开发中最常用的语法模式,每个示例都经过生产环境验证。
2. 基础语法结构精要
2.1 变量与可变性
Rust的变量声明使用let关键字,默认不可变是其重要特性:
rust复制let x = 5; // 不可变绑定
let mut y = 10; // 可变绑定
y += 1; // 合法操作
// x = 6; 编译错误!
经验:在大型项目中,建议优先使用不可变绑定,只有在确实需要修改时才使用
mut。这能显著减少并发场景下的数据竞争风险。
2.2 基本数据类型
Rust是静态类型语言,但支持类型推断:
rust复制let a: i32 = 42; // 显式标注
let b = 3.14; // 自动推断为f64
let c = true; // bool类型
let d = '🦀'; // Unicode字符
复合类型中,元组和数组最常用:
rust复制let tuple: (i32, f64, char) = (1, 2.0, '3');
let arr = [1, 2, 3]; // 固定长度数组
let slice = &arr[1..3]; // 切片引用
3. 核心概念深度解析
3.1 所有权系统
这是Rust最独特的机制,理解它才能避免编译错误:
rust复制let s1 = String::from("hello");
let s2 = s1; // 所有权转移
// println!("{}", s1); 错误!s1已失效
let x = 5;
let y = x; // 基本类型自动拷贝
println!("{}", x); // 合法
所有权规则:
- 每个值有且只有一个所有者
- 当所有者离开作用域,值被丢弃
- 赋值、传参可能导致所有权转移
3.2 借用与生命周期
引用(借用)是避免所有权转移的关键:
rust复制fn calculate_length(s: &String) -> usize {
s.len()
}
let s = String::from("hello");
let len = calculate_length(&s); // 借用而非转移
println!("{} remains valid", s);
生命周期标注示例:
rust复制fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
4. 常用数据结构操作
4.1 Vec动态数组
rust复制let mut vec = Vec::new();
vec.push(1);
vec.push(2);
let third = &vec[2]; // 索引访问
let maybe = vec.get(2); // 安全访问
for i in &vec {
println!("{}", i);
}
4.2 HashMap与BTreeMap对比
| 特性 | HashMap | BTreeMap |
|---|---|---|
| 排序 | 无序 | 按键排序 |
| 时间复杂度 | O(1)平均 | O(log n) |
| 内存占用 | 较高 | 较低 |
| 适用场景 | 快速查找 | 范围查询 |
rust复制use std::collections::{HashMap, BTreeMap};
let mut hash = HashMap::new();
hash.insert("blue", 10);
let mut tree = BTreeMap::new();
tree.insert("red", 20);
5. 错误处理最佳实践
5.1 Result与unwrap
rust复制use std::fs::File;
let f = File::open("hello.txt"); // 返回Result
match f {
Ok(file) => println!("File opened"),
Err(error) => println!("Error: {:?}", error),
}
// let f = File::open("hello.txt").unwrap(); // 危险!
let f = File::open("hello.txt").expect("Failed to open"); // 带错误信息
5.2 ?运算符简化
rust复制use std::io::{self, Read};
fn read_username() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
6. 并发编程模式
6.1 线程基础
rust复制use std::thread;
let handle = thread::spawn(|| {
println!("Hello from thread!");
});
handle.join().unwrap();
6.2 通道通信
rust复制use std::sync::mpsc;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(42).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
7. 实用宏与特性
7.1 常用内置宏
rust复制println!("Hello {}", "world"); // 格式化输出
assert_eq!(2+2, 4); // 测试断言
vec![1, 2, 3]; // 快速创建Vec
7.2 自定义宏
rust复制macro_rules! say_hello {
() => {
println!("Hello!");
};
}
say_hello!();
8. 模块系统组织
8.1 基本模块结构
code复制src/
├── main.rs
├── lib.rs
└── network/
├── mod.rs
└── server.rs
模块声明示例:
rust复制// src/lib.rs
pub mod network;
// src/network/mod.rs
pub mod server;
8.2 可见性控制
rust复制mod outermost {
pub fn middle_function() {}
pub mod inner {
pub fn inner_function() {
super::middle_function();
}
}
}
9. 异步编程入门
9.1 async/await基础
rust复制use tokio::time::{sleep, Duration};
async fn say_after(sec: u64, msg: &str) {
sleep(Duration::from_secs(sec)).await;
println!("{}", msg);
}
#[tokio::main]
async fn main() {
let task1 = say_after(1, "hello");
let task2 = say_after(2, "world");
tokio::join!(task1, task2);
}
9.2 常见异步模式
| 模式 | 适用场景 | 典型实现 |
|---|---|---|
| spawn | 独立后台任务 | tokio::spawn |
| select! | 多路复用 | tokio::select |
| join! | 等待多个任务完成 | tokio::join |
| Mutex | 共享状态保护 | tokio::sync::Mutex |
10. 测试与文档规范
10.1 单元测试
rust复制#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
#[should_panic]
fn test_panic() {
panic!("This test should fail");
}
}
10.2 文档测试
rust复制/// 加法函数示例
///
/// # Examples
///
/// ```
/// let result = my_crate::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
11. 性能优化技巧
11.1 避免不必要的拷贝
rust复制// 不佳实现
fn process(data: Vec<u8>) {
// ...
}
// 改进方案
fn process(data: &[u8]) {
// ...
}
11.2 使用迭代器代替索引
rust复制let v = vec![1, 2, 3];
// 传统方式
for i in 0..v.len() {
println!("{}", v[i]);
}
// 更高效的方式
for num in &v {
println!("{}", num);
}
12. 开发环境配置
12.1 国内镜像设置
在~/.cargo/config中添加:
toml复制[source.crates-io]
replace-with = 'ustc'
[source.ustc]
registry = "https://mirrors.ustc.edu.cn/crates.io-index"
12.2 常用工具链
bash复制# 安装组件
rustup component add clippy rustfmt
# 代码格式化
cargo fmt
# 静态检查
cargo clippy
在编写Rust代码时,我强烈建议保持rust-analyzer插件实时运行,它能即时反馈所有权错误和类型问题。对于复杂的所有权场景,可以先用Rc<RefCell<T>>快速实现功能,待逻辑稳定后再考虑优化为更高效的方案。
