资讯动态

Rust 的设计模式2

发布时间:2026/10/3 2:41:18 来源:尧图企业网站定制
Rust 的设计模式生态比较特殊——它既有从 OOP 世界搬来的经典模式但往往需要改造也有大量**Rust 特有的、由所有权/借用/生命周期/零成本抽象催生的惯用法**。下面按类别梳理一下。## 一、先理解 Rust 的约束经典 GoF 模式很多是为弥补语言缺陷而生的Rust 里情况不同| 约束 | 影响 ||---|---|| 无继承、无传统 OOP | 策略/模板方法等改用 trait 泛型/枚举 || 所有权、借用检查 | 不能随意共享可变状态催生 Rc/RefCell/Arc/Mutex 模式 || 无 null | 用 OptionT催生 typestate、newtype 等 || 编译期多态泛型vs 运行期多态trait object | 影响性能与灵活性权衡 || 无 GC | RAII、Drop、智能指针成为核心 |## 二、Rust 中常见的经典模式改造版### 1. 策略模式用 trait 替代接口继承rusttrait Compression {fn compress(self, data: [u8]) - Vecu8;}struct Gzip;impl Compression for Gzip { /* ... */ }struct Zstd;impl Compression for Zstd { /* ... */ }// 静态分发编译期零成本fn saveC: Compression(c: C, data: [u8]) { c.compress(data); }// 动态分发运行期可存放异构集合fn save_dyn(c: dyn Compression, data: [u8]) { c.compress(data); }选择性能敏感用泛型需要异构集合/插件用 dyn。### 2. 建造者模式BuilderRust 里极其常用尤其是结构体字段多、有默认值时。有两种风格rust// 风格 A链式消费 selfstruct Config { host: String, port: u16, tls: bool }struct ConfigBuilder { host: String, port: u16, tls: bool }impl ConfigBuilder {fn new() - Self { Self { host: localhost.into(), port: 80, tls: false } }fn port(mut self, p: u16) - Self { self.port p; self }fn tls(mut self, v: bool) - Self { self.tls v; self }fn build(self) - Config { Config { host: self.host, port: self.port, tls: self.tls } }}// 风格 Bmut self 最终 build(self)// 适合需要复用 builder 的场景### 3. 新类型模式Newtype用元组结构体包裹类型获得类型安全 可为外部类型实现外部 trait绕过孤儿规则ruststruct Meters(f64);struct Feet(f64);// 不会把 Feet 误传给要 Meters 的函数// 为外部类型实现外部 traitstruct Wrapper(VecString);impl std::fmt::Display for Wrapper {fn fmt(self, f: mut std::fmt::Formatter) - std::fmt::Result {write!(f, [{}], self.0.join(, ))}}### 4. 迭代器 / 适配器模式Rust 把迭代器 组合子做到了语言级比经典 Iterator 模式强大得多rustlet sum: i32 v.iter().filter(|x| **x 0).map(|x| x * 2).take(5).sum();自定义迭代器只需实现 Iterator配合 impl Iterator 返回是零成本抽象的代表。### 5. 观察者模式Rust 里没有内建通常用通道channel或回调实现但要小心借用问题rust// 用 channel 解耦推荐let (tx, rx) std::sync::mpsc::channel();// 发布者持有 tx订阅者持有 rx// 或用 ArcMutexVecBoxdyn Fn(Event)### 6. 状态模式两种思路- 传统 OOPtrait object 存状态方法里 self.state Box::new(...)但状态切换时所有权/借用较别扭。- Rust 惯用**用枚举 match 表达状态机**把非法状态变成不可表示。rustenum State { Idle, Running, Done }struct Machine { state: State }impl Machine {fn step(mut self) {self.state match self.state {State::Idle State::Running,State::Running State::Done,State::Done State::Done,};}}## 三、Rust 特有的惯用法模式### 1. RAII Drop资源获取即初始化Drop 做清理是 Rust 内存安全与锁管理的基石ruststruct Guarda, T(a MutexT);// 离开作用域自动释放锁### 2. Typestate类型状态机用类型参数编码状态让**编译期**拒绝非法操作ruststruct Locked;struct Unlocked;struct DoorState { _s: PhantomDataState }impl DoorLocked {fn unlock(self) - DoorUnlocked { Door { _s: PhantomData } }}impl DoorUnlocked {fn open(self) {}fn lock(self) - DoorLocked { Door { _s: PhantomData } }}// DoorLocked 没有 open()编译不过### 3. 内部可变性Interior Mutability外部 self 下修改内部状态用 Cell/RefCell/Mutex/RwLockrustuse std::cell::RefCell;use std::rc::Rc;let shared Rc::new(RefCell::new(vec![1, 2, 3]));shared.borrow_mut().push(4); // 运行期借用检查选择- 单线程 Copy → Cell- 单线程 非 Copy → RefCell- 多线程 → Mutex / RwLock / Atomic*### 4. 扩展 traitExtension Trait给外部类型加方法像 Kotlin/Swift 扩展rusttrait VecExtT {fn second(self) - OptionT;}implT VecExtT for VecT {fn second(self) - OptionT { self.get(1) }}### 5. 密封 traitSealed Trait限制 trait 只能在你的 crate 内实现用私有 supertraitrustmod private { pub trait Sealed {} }pub trait MyTrait: private::Sealed { /* ... */ }### 6. 幽灵类型PhantomData表达逻辑上拥有/关联 T但字段里没有 Truststruct TagT { _marker: PhantomDataT }### 7. Deref 多态 / 智能指针模式Box/Rc/Arc 用 Deref 让调用透明String: DerefTargetstr。### 8. 小字符串/小向量优化SSO如 smallvec、smol_str栈上存小数据避免堆分配。### 9. Cow写时克隆Cowa, str 延迟分配读多写少时省拷贝。### 10. 静态断言 / 编译期检查用 const 上下文或 static_assertions crate 在编译期验证假设。## 四、并发相关模式| 模式 | 工具 ||---|---|| 共享可变状态 | ArcMutexT / ArcRwLockT || 无锁 | AtomicUsize、crossbeam || 消息传递 | std::sync::mpsc、crossbeam-channel、tokio::sync::mpsc || Actor | actix、ractor || 工作窃取 | rayon 的并行迭代器 || 作用域线程 | std::thread::scope、rayon::scope |## 五、学习资源推荐1. **《Rust 设计模式》在线书**rust-unofficial/patterns——社区维护最权威的 Rust 惯用法集合。2. **《Rust for Rustaceans》**Jon Gjengset——深入 trait、类型系统、并发模式。3. **《Programming Rust》**OReilly——系统讲解所有权与抽象。4. **GoF《设计模式》**——读的时候要带着Rust 里是否需要它的批判视角。## 六、核心心法 **不要把 OOP 模式硬套到 Rust。** Rust 的很多模式其实是类型系统帮你把错误从运行期搬到编译期newtype 防混淆、typestate 防非法状态、Option 防 null、所有权防数据竞争。设计时优先问能否用类型表达约束而不是用哪个 GoF 模式如果你有具体场景比如想做插件系统、状态机、异步任务编排我可以给出针对性的 Rust 实现方案。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑