m12-lifecycle by zhanghandong/rust-skills
npx skills add https://github.com/zhanghandong/rust-skills --skill m12-lifecycle第二层:设计选择
此资源应在何时创建、使用和清理?
在实现生命周期之前:
| 模式 | 时机 | 实现 |
|---|---|---|
| RAII | 自动清理 | Drop trait |
| 惰性初始化 | 延迟创建 | OnceLock, LazyLock |
| 池 | 重用昂贵资源 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
r2d2, deadpool |
| 守卫 | 作用域访问 | MutexGuard 模式 |
| 作用域 | 事务边界 | 自定义结构体 + Drop |
设计生命周期前:
资源成本如何?
作用域是什么?
错误处理如何?
到领域约束(第三层):
"我应该如何管理数据库连接?"
↑ 问:连接成本如何?
↑ 检查:domain-*(延迟要求)
↑ 检查:基础设施(连接限制)
| 问题 | 追溯至 | 提问 |
|---|---|---|
| 连接池 | domain-* | 可接受的延迟是多少? |
| 资源限制 | domain-* | 基础设施约束是什么? |
| 事务作用域 | domain-* | 哪些操作必须是原子的? |
到实现(第一层):
"需要自动清理"
↓ m02-resource: 实现 Drop
↓ m01-ownership: 明确清理责任方
"需要惰性初始化"
↓ m03-mutability: 使用 OnceLock 实现线程安全
↓ m07-concurrency: 使用 LazyLock 实现同步
"需要连接池"
↓ m07-concurrency: 线程安全的池
↓ m02-resource: 使用 Arc 共享
| 模式 | 类型 | 用例 |
|---|---|---|
| RAII | Drop trait | 作用域退出时自动清理 |
| 惰性初始化 | OnceLock, LazyLock | 延迟初始化 |
| 池 | r2d2, deadpool | 连接重用 |
| 守卫 | MutexGuard | 作用域锁释放 |
| 作用域 | 自定义结构体 | 事务边界 |
| 事件 | Rust 机制 |
|---|---|
| 创建 | new(), Default |
| 惰性初始化 | OnceLock::get_or_init |
| 使用 | &self, &mut self |
| 清理 | Drop::drop() |
struct FileGuard {
path: PathBuf,
_handle: File,
}
impl Drop for FileGuard {
fn drop(&mut self) {
// 清理:删除临时文件
let _ = std::fs::remove_file(&self.path);
}
}
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 | 实现 Drop 或 RAII 包装器 |
| 双重释放 | 手动管理内存 | 让 Rust 处理 |
| 释放后使用 | 悬垂引用 | 检查生命周期 |
| E0509 从 Drop 中移出 | 移动了拥有所有权的字段 | Option::take() |
| 池耗尽 | 未归还资源 | 确保 Drop 会归还 |
| 反模式 | 为何不好 | 更好的做法 |
|---|---|---|
| 手动清理 | 容易忘记 | RAII/Drop |
lazy_static! | 外部依赖 | std::sync::OnceLock |
| 全局可变状态 | 线程不安全 | OnceLock 或适当的同步 |
| 忘记关闭 | 资源泄漏 | 实现 Drop |
| 时机 | 参见 |
|---|---|
| 智能指针 | m02-resource |
| 线程安全初始化 | m07-concurrency |
| 领域作用域 | m09-domain |
| 清理中的错误 | m06-error-handling |
每周安装量
602
仓库
GitHub 星标数
912
首次出现
Jan 20, 2026
安全审计
安装于
opencode554
codex534
gemini-cli523
github-copilot510
amp463
kimi-cli459
Layer 2: Design Choices
When should this resource be created, used, and cleaned up?
Before implementing lifecycle:
| Pattern | When | Implementation |
|---|---|---|
| RAII | Auto cleanup | Drop trait |
| Lazy init | Deferred creation | OnceLock, LazyLock |
| Pool | Reuse expensive resources | r2d2, deadpool |
| Guard | Scoped access | MutexGuard pattern |
| Scope | Transaction boundary | Custom struct + Drop |
Before designing lifecycle:
What's the resource cost?
What's the scope?
What about errors?
To domain constraints (Layer 3):
"How should I manage database connections?"
↑ Ask: What's the connection cost?
↑ Check: domain-* (latency requirements)
↑ Check: Infrastructure (connection limits)
| Question | Trace To | Ask |
|---|---|---|
| Connection pooling | domain-* | What's acceptable latency? |
| Resource limits | domain-* | What are infra constraints? |
| Transaction scope | domain-* | What must be atomic? |
To implementation (Layer 1):
"Need automatic cleanup"
↓ m02-resource: Implement Drop
↓ m01-ownership: Clear owner for cleanup
"Need lazy initialization"
↓ m03-mutability: OnceLock for thread-safe
↓ m07-concurrency: LazyLock for sync
"Need connection pool"
↓ m07-concurrency: Thread-safe pool
↓ m02-resource: Arc for sharing
| Pattern | Type | Use Case |
|---|---|---|
| RAII | Drop trait | Auto cleanup on scope exit |
| Lazy Init | OnceLock, LazyLock | Deferred initialization |
| Pool | r2d2, deadpool | Connection reuse |
| Guard | MutexGuard | Scoped lock release |
| Event | Rust Mechanism |
|---|---|
| Creation | new(), Default |
| Lazy Init | OnceLock::get_or_init |
| Usage | &self, &mut self |
| Cleanup | Drop::drop() |
struct FileGuard {
path: PathBuf,
_handle: File,
}
impl Drop for FileGuard {
fn drop(&mut self) {
// Cleanup: remove temp file
let _ = std::fs::remove_file(&self.path);
}
}
use std::sync::OnceLock;
static CONFIG: OnceLock<Config> = OnceLock::new();
fn get_config() -> &'static Config {
CONFIG.get_or_init(|| {
Config::load().expect("config required")
})
}
| Error | Cause | Fix |
|---|---|---|
| Resource leak | Forgot Drop | Implement Drop or RAII wrapper |
| Double free | Manual memory | Let Rust handle |
| Use after drop | Dangling reference | Check lifetimes |
| E0509 move out of Drop | Moving owned field | Option::take() |
| Pool exhaustion | Not returned | Ensure Drop returns |
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Manual cleanup | Easy to forget | RAII/Drop |
lazy_static! | External dep | std::sync::OnceLock |
| Global mutable state | Thread unsafety | OnceLock or proper sync |
| Forget to close | Resource leak | Drop impl |
| When | See |
|---|---|
| Smart pointers | m02-resource |
| Thread-safe init | m07-concurrency |
| Domain scopes | m09-domain |
| Error in cleanup | m06-error-handling |
Weekly Installs
602
Repository
GitHub Stars
912
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode554
codex534
gemini-cli523
github-copilot510
amp463
kimi-cli459
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
103,800 周安装
| Scope | Custom struct | Transaction boundaries |