aboutsummaryrefslogtreecommitdiff
path: root/docs/_zh_CN/pages/concepts/2-resource.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/_zh_CN/pages/concepts/2-resource.md')
-rw-r--r--docs/_zh_CN/pages/concepts/2-resource.md60
1 files changed, 60 insertions, 0 deletions
diff --git a/docs/_zh_CN/pages/concepts/2-resource.md b/docs/_zh_CN/pages/concepts/2-resource.md
new file mode 100644
index 0000000..1052254
--- /dev/null
+++ b/docs/_zh_CN/pages/concepts/2-resource.md
@@ -0,0 +1,60 @@
+<h1 align="center">资源系统</h1>
+<p align="center">
+ Mingling 如何管理全局状态
+</p>
+
+命令行程序经常需要共享一些全局的东西——配置文件、数据库连接、计数器、当前工作目录。
+
+在普通 Rust 里你可能会用 `OnceCell` 或 `lazy_static`,在 Mingling 里有一套统一的机制:**资源系统**。
+
+## 什么是资源?
+
+资源就是在多个 Chain 和 Renderer 之间共享的数据。
+
+你只需要定义一个类型、注册到 Program,然后在函数签名里声明你需要它——剩下的注入和生命周期管理都由框架完成。
+
+## 核心机制:ResourceMarker
+
+任何同时实现了 `Default + Clone` 的类型都可以自动成为资源。框架会为它实现 `ResourceMarker` trait,使其具备:
+
+- **`res_clone()`** —— 当多个 Chain 同时访问时,框架可以通过 clone 来避免锁竞争
+- **`res_default()`** —— 资源未注册时提供兜底值
+
+如果你需要更精细的生命周期控制,可以使用 `LazyRes<T>`。它允许资源在第一次被访问时才初始化,并且可以在析构时执行回调(比如退出前保存状态到磁盘)。
+
+## 为什么不用全局变量?
+
+传统做法的静态变量是隐式依赖 —— 你看函数签名根本不知道它用了什么全局状态。而 Mingling 的资源注入让 **依赖显式化**:
+
+- 函数需要什么资源,参数列表就写什么
+- `&T` 表示只读访问,`&mut T` 表示可修改
+- 调用者一眼就能看出这个函数的副作用
+
+例如:
+
+```rust
+@@@ use mingling::res::ResExitCode;
+@@@ pack!(ErrorFileNotFound = ());
+#[chain]
+fn handle_error_file_not_found(
+ error: ErrorFileNotFound,
+ ec: &mut ResExitCode // 通过签名可以看出副作用!
+) {
+ ec.exit_code = 2; // 这里修改了退出码
+}
+```
+
+## 资源与 Setup 的关系
+
+资源通常通过两个途径注册到 Program:
+
+1. **直接注册** —— 在 `main` 中调用 `program.with_resource(...)`
+2. **通过 Setup** —— 使用 `DirectoryEnvironmentSetup` 等内置 Setup 批量注册(如 `ResCurrentDir`、`ResHomeDir`)
+
+Setup 是比资源更高层的抽象,一个 Setup 可以注册多个资源并做其他初始化工作。
+
+详见教程中的 [程序装配](./pages/8-setup-and-resources) 一章。
+
+<p align="center" style="font-size: 0.85em; color: gray;">
+ Written by @Weicao-CatilGrass
+</p>