其他
设计 Rust 资源生命周期时,用 RAII、惰性初始化…
适用于 Rust 中需要决定资源何时创建、由谁持有、何时清理,并处理错误路径与作用域边界的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 54/100 ×0.15
适用场景
设计 Rust 资源生命周期时,用 RA通用
解决思路
- 实现生命周期前,明确资源的作用域、清理责任归属、出错时的清理行为。
- 按资源成本选择创建策略:便宜资源每次使用创建;昂贵资源用池或缓存;全局资源用惰性单例。
- 按作用域选择存储:函数局部用栈分配;请求级通过传参或提取;应用级用 static 或 Arc。
- 按错误清理要求选择:必须清理时用 Drop;清理可选时显式 close;清理可能失败时让 close 返回 Result。
- RAII:需要自动清理时实现 Drop trait。
- Lazy init:需要延迟创建时使用 OnceLock、LazyLock。
- Pool:需要复用昂贵资源时使用 r2d2、deadpool。
- Guard:需要作用域访问时采用 MutexGuard 模式。
- Scope:需要事务边界时使用自定义 struct + Drop。
- 管理数据库连接时,先问连接成本,向上追踪 domain-* 的延迟要求,并检查 Infrastructure 的连接限制。
- 设计连接池时,追踪到 domain-*,确认可接受延迟。
- 设计资源限制时,追踪到 domain-*,确认基础设施约束。
- 设计事务作用域时,追踪到 domain-*,确认必须原子化的内容。
- 需要自动清理时,向下到 m02-resource 实现 Drop,并在 m01-ownership 中明确 owner 以负责清理。
- 需要惰性初始化时,向下到 m03-mutability 使用 OnceLock 实现线程安全,向下到 m07-concurrency 使用 LazyLock 实现同步。
- 需要连接池时,向下到 m07-concurrency 使用线程安全池,向下到 m02-resource 用 Arc 共享。
- 生命周期事件-创建:使用 new()、Default。
- 生命周期事件-惰性初始化:使用 OnceLock::get_or_init。
- 生命周期事件-使用:使用 &self、&mut self。
- 生命周期事件-清理:实现 Drop::drop()。
- RAII Guard 模板:定义 FileGuard { path: PathBuf, _handle: File };实现 Drop for FileGuard,在 drop 中用 std::fs::remove_file(&self.path) 清理临时文件。
- Lazy Singleton 模板:使用 use std::sync::OnceLock; static CONFIG: OnceLock<Config> = OnceLock::new(); 定义 fn get_config() -> &'static Config,使用 CONFIG.get_or_init(|| Config::load().expect("config required"))。
- 修复资源泄漏:实现 Drop 或 RAII 包装。
- 修复 double free:不要手动管理内存,让 Rust 处理。
- 修复 use after drop:检查生命周期。
- 修复 E0509 move out of Drop:使用 Option::take()。
- 修复 pool exhaustion:确保 Drop 归还连接。
- 反模式修复:手动清理改为 RAII/Drop。
- 反模式修复:lazy_static! 改为 std::sync::OnceLock。
- 反模式修复:全局可变状态改为 OnceLock 或 proper sync。
- 反模式修复:忘记 close 改为 Drop impl。
- 相关技能:智能指针看 m02-resource。
- 相关技能:线程安全 init 看 m07-concurrency。
- 相关技能:Domain scopes 看 m09-domain。
- 相关技能:清理中的错误处理看 m06-error-handling。
适用边界 · 注意事项
- 当资源清理必须依赖异步运行时、外部确认或清理顺序复杂且 Drop 无法安全或可失败表达时,不应只依赖 Drop/RAII。
- 当资源极便宜且无外部句柄或状态时,无需引入池、惰性单例或额外 RAII 包装。
- 当需要手动精细控制释放时机且清理失败必须显式处理时,使用显式 close + Result 而非仅 Drop。