Rust 速查表

随手查阅 Rust 1.98 的核心语法、错误处理、并发、异步与工具链用法。

Rust 1.98 打印为 1 页
下载 .md

绑定与控制流

let value = source; 绑定不可变局部变量;需要改变类型时,用新的 let 遮蔽它
let mut count = 0; 允许重新赋值和原地修改
const LIMIT: usize = 100; 声明带类型的编译期常量
let Some(id) = maybe_id else { return; }; 匹配到 Some 时取出值,否则退出当前控制流
match result { Ok(value) => value, Err(error) => return Err(error) } 穷尽处理所有变体,并原样返回错误
while let Some(item) = stack.pop() { consume(item); } 持续取值,直到模式不再匹配

所有权与借用

inspect(&value); 借出共享访问权,不转移所有权
update(&mut value); 借出独占可变访问权,直到该借用最后一次使用
let moved = value; 转移所有权;除非类型实现 Copy,否则原绑定失效
let copied = number; 复制实现 Copy 的值,使两个绑定都可继续使用
let cloned = value.clone(); 通过 Clone 显式创建副本
let old = std::mem::take(&mut value); Default::default() 替换原值,并取得旧值的所有权
drop(guard); 在作用域结束前释放拥有的资源

字符串与集合

fn normalize(text: &str) -> String { text.trim().to_owned() } 借用 UTF-8 输入,返回拥有所有权的文本
text.chars() 迭代 Unicode 标量值,而不是字素簇
text.as_bytes() 不分配内存,直接借用底层 UTF-8 字节
String::from_utf8(bytes)? 校验 UTF-8,并复用拥有所有权的字节缓冲区
Vec::with_capacity(count) 已知预计元素数量时预留空间
counts.entry(key).or_insert(0) 为缺失的映射项插入默认值,并取得可变借用
queue.pop_front() Option 返回并移除 VecDeque 中最早的元素

迭代器与闭包

items.iter() 生成共享引用,并保留集合所有权
items.iter_mut() 生成独占引用,用于原地修改
items.into_iter() 消耗集合,并生成拥有所有权的元素
iter.filter_map(parse).collect::<Vec<_>>() 丢弃 None,收集成功转换的值
iter.collect::<Result<Vec<_>, _>>()? 收集成功值,遇到第一个错误时停止
move |item| process(item, &config) 按值捕获 config,让闭包可以活得比当前作用域更久
F: FnMut(&Item) -> bool 接受可重复调用且能修改捕获状态的谓词

trait 与类型

#[derive(Debug, Clone, PartialEq)] struct Point(i32, i32); 为数据类型生成标准 trait 实现
struct UserId(u64); 使用 newtype 模式为基本类型赋予独立的领域类型
enum State<T> { Ready(T), Closed } 用可携带数据的变体描述封闭状态集合
fn show<T: Display>(value: &T) { println!("{value}"); } 用泛型 trait 约束要求一种能力
trait Source { type Item; fn next(&mut self) -> Option<Self::Item>; } 让每个实现选择一种关联项类型
Box<dyn Draw + Send> 拥有可跨线程传递、隐藏具体类型的实现者
<User as Display>::fmt(&user, formatter) 用完全限定语法明确选择 trait 实现

Option 与 Result

type LoadResult<T> = Result<T, LoadError>; 为可复用的结果类型命名,同时保留明确的错误类型
let value = operation()?; 成功时取值,失败时立即返回转换后的残差
option.ok_or_else(|| Error::Missing(key))? 把缺失值转换为按需构造的错误
option.and_then(parse) 串联另一个返回 Option 的函数
result.map(transform) 只转换成功值
result.map_err(Error::from) 只转换错误值
matches!(status, Status::Ready(_)) 测试模式是否匹配,并返回布尔值

anyhow 与 thiserror

type AppResult<T> = anyhow::Result<T>; 在应用边界擦除具体错误类型
read(path).with_context(|| format!("reading {path}"))? 导入 anyhow::Context 后,仅在失败时添加上下文
anyhow::bail!("invalid port: {port}"); 立即返回临时构造的应用错误
anyhow::ensure!(port > 0, "port must be positive"); 条件不成立时返回应用错误
#[derive(Debug, thiserror::Error)] enum LoadError { #[error("missing config")] Missing } 定义可供调用方匹配的具体错误类型
#[error("cannot read {path}: {source}")] Read { path: PathBuf, #[source] source: std::io::Error } 格式化变体,同时保留底层错误源
Io(#[from] std::io::Error) 为变体生成 From 转换和错误源报告

线程与共享状态

let handle = std::thread::spawn(move || work(data)); 把任务数据的所有权移入新的操作系统线程
let result = handle.join().expect("worker panicked"); 等待线程结束,并明确暴露 panic
let shared = Arc::new(Mutex::new(value)); 组合共享所有权与同步可变性
let mut guard = shared.lock().unwrap(); 取得可变访问权;需要恢复时应处理锁中毒
let read_guard = lock.read().unwrap(); 通过 RwLock 守卫允许多个读取者并发访问
let (sender, receiver) = std::sync::mpsc::sync_channel(capacity); 创建有界通道,缓冲区满时施加背压
sender.send(value)?; 把值转移给接收端;连接断开时返回错误

异步与 Tokio

async fn fetch() -> Result<Data, Error> { request().await } 返回 future,其函数体在被轮询时才运行
let value = future.await?; 暂停到操作完成,并传播失败
let handle = tokio::spawn(async move { work(data).await }); 在运行时中生成拥有数据的 Send + 'static 任务
let (left, right) = tokio::try_join!(load_a(), load_b())?; 并发推进可失败的 future,遇到错误时停止
tokio::select! { value = task => value, } 竞速已启用的分支;未胜出的 future 必须可安全取消
let value = tokio::time::timeout(duration, operation()).await??; 限制等待时间,并传播超时错误和操作错误
tokio::task::spawn_blocking(|| blocking_work()).await?; 把阻塞工作移出异步工作线程

模块与 Cargo

mod parser; 声明模块,由编译器按模块规则查找其源文件
use crate::parser::parse; 从当前 crate 根开始把条目引入作用域
pub(crate) fn helper() {} 只在当前 crate 内公开条目
pub use api::Client; 把条目重导出为公共 API 的一部分
cargo check --all-targets --all-features 启用全部 feature,对所有 target 做类型检查
cargo test --workspace 运行工作区内所有 package 的测试
cargo clippy --all-targets --all-features -- -D warnings 检查所有 target,并把任何警告视为失败

unsafe 与 FFI

let ptr = &raw const value; 创建原始指针,不产生中间引用
let ptr = NonNull::new(ptr).ok_or(Error::Null)?; 拒绝空指针,但不假定指针满足其他有效性条件
let value = unsafe { ptr.read() }; 仅在确认对齐、初始化和有效性后读取
let slice = unsafe { std::slice::from_raw_parts(ptr, len) }; 仅在证明整段内存满足契约后构造切片
#[repr(C)] struct Header { tag: u32, len: usize } 为 FFI 数据结构指定与 C 兼容的字段布局
unsafe extern "C" { fn strlen(s: *const c_char) -> usize; } 声明 Rust 无法验证调用契约的外部函数
let text = unsafe { CStr::from_ptr(ptr) }; 仅在确认终止符和指针有效性后借用 C 字符串

向你的 AI 准确表达

规则包 · Rust

供编码智能体使用的 Rust 规则

下载本方向的常见陷阱与审查项,文件格式可直接供编码智能体读取。