
关于
惯用 Rust 模式、所有权、错误处理、Trait、并发和构建安全高性能应用的最佳实践。
name: rust-patterns description: 惯用 Rust 模式、所有权、错误处理、trait、并发以及构建安全高性能应用的最佳实践。 origin: ECC
Rust 开发模式
用于构建安全、高性能和可维护应用的惯用 Rust 模式和最佳实践。
何时使用
- 编写新的 Rust 代码
- 审查 Rust 代码
- 重构现有 Rust 代码
- 设计 crate 结构和模块布局
工作原理
本技能在六个关键领域强制执行惯用 Rust 约定:所有权和借用以在编译时防止数据竞争,使用 Result/? 错误传播(库使用 thiserror,应用使用 anyhow),枚举和穷举模式匹配使非法状态不可表示,trait 和泛型实现零成本抽象,通过 Arc<Mutex<T>>、通道和 async/await 实现安全并发,以及按领域组织的最小 pub 表面。
核心原则
1. 所有权和借用
Rust 的所有权系统在编译时防止数据竞争和内存错误。
// 好:不需要所有权时传递引用
fn process(data: &[u8]) -> usize {
data.len()
}
// 好:仅在需要存储或消费时获取所有权
fn store(data: Vec<u8>) -> Record {
Record { payload: data }
}
// 差:不必要地克隆以避免借用检查器
fn process_bad(data: &Vec<u8>) -> usize {
let cloned = data.clone(); // 浪费——只需借用
cloned.len()
}
使用 Cow 实现灵活所有权
use std::borrow::Cow;
fn normalize(input: &str) -> Cow<'_, str> {
if input.contains(' ') {
Cow::Owned(input.replace(' ', "_"))
} else {
Cow::Borrowed(input) // 不需要修改时零成本
}
}
错误处理
使用 Result 和 ? — 生产代码中永远不要 unwrap()
// 好:带上下文传播错误
use anyhow::{Context, Result};
fn load_config(path: &str) -> Result<Config> {
let content = std::fs::read_to_string(path)
.with_context(|| format!("failed to read config from {path}"))?;
let config: Config = toml::from_str(&content)
.with_context(|| format!("failed to parse config from {path}"))?;
Ok(config)
}
// 差:出错时 panic
fn load_config_bad(path: &str) -> Config {
let content = std::fs::read_to_string(path).unwrap(); // Panic!
toml::from_str(&content).unwrap()
}
库错误用 thiserror,应用错误用 anyhow
// 库代码:结构化、类型化的错误
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StorageError {
#[error("record not found: {id}")]
NotFound { id: String },
#[error("connection failed")]
Connection(#[from] std::io::Error),
#[error("invalid data: {0}")]
InvalidData(String),
}
// 应用代码:灵活的错误处理
use anyhow::{bail, Result};
fn run() -> Result<()> {
let config = load_config("app.toml")?;
if config.workers == 0 {
bail!("worker count must be > 0");
}
Ok(())
}
Option 组合子优于嵌套匹配
// 好:组合子链
fn find_user_email(users: &[User], id: u64) -> Option<String> {
users.iter()
.find(|u| u.id == id)
.map(|u| u.email.clone())
}
// 差:深度嵌套匹配
fn find_user_email_bad(users: &[User], id: u64) -> Option<String> {
match users.iter().find(|u| u.id == id) {
Some(user) => match &user.email {
email => Some(email.clone()),
},
None => None,
}
}
枚举和模式匹配
将状态建模为枚举
// 好:不可能的状态不可表示
enum ConnectionState {
Disconnected,
Connecting { attempt: u32 },
Connected { session_id: String },
Failed { reason: String, retries: u32 },
}
fn handle(state: &ConnectionState) {
match state {
ConnectionState::Disconnected => connect(),
ConnectionState::Connecting { attempt } if *attempt > 3 => give_up(),
ConnectionState::Connecting { .. } => wait(),
ConnectionState::Connected { session_id } => use_session(session_id),
ConnectionState::Failed { retries, .. } if *retries < 3 => retry(),
ConnectionState::Failed { reason, .. } => report_failure(reason),
}
}
兼容工具
Claude CodeCursor
标签
前端开发
