# Rust 速查表

Source: https://codewiki.com/zh/cheatsheets/rust/

## 绑定与控制流

- `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 { 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>` — 拥有可跨线程传递、隐藏具体类型的实现者
- `::fmt(&user, formatter)` — 用完全限定语法明确选择 trait 实现

## Option 与 Result

- `type LoadResult = 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 = anyhow::Result;` — 在应用边界擦除具体错误类型
- `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 字符串
