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规则

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