mcpField
M
m03-mutability

m03-mutability

github.com/actionbook开发1.6k3.4k 次安装9 周前更新
代码仓库

关于 m03-mutability

面向 Rust 编程的技能,帮助判断数据是否需要可变以及如何管理可变性。内容说明借用规则,并按线程环境和数据类型比较内部可变性方案。

主要功能

  1. 01判断是否需要修改数据
  2. 02比较内部可变性模式
  3. 03运用借用规则
  4. 04选择线程安全的修改方式

适用场景

  1. 01通过重构解决借用冲突
  2. 02为单线程代码选择 Cell 或 RefCell
  3. 03为并发数据选择 Mutex、RwLock 或原子类型

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/actionbook/rust-skills --skill m03-mutability

安装后在 Claude Code 中输入/m03-mutability确认已加载。

详细介绍

可变性

第 1 层:语言机制

核心问题

为什么这份数据需要改变?谁可以改变它?

在添加内部可变性之前,请先了解:

  • 可变性是必需的,还是意外复杂性?
  • 谁应该控制可变性?
  • 这种可变模式安全吗?

错误 → 设计问题

错误不要只说应该这样问
E0596“添加 mut”它真的应该是可变的吗?
E0499“拆分借用”数据结构是否合适?
E0502“分隔作用域”为什么我们需要同时持有这两种借用?
RefCell panic“使用 try_borrow”运行时检查是否合适?

思考提示

添加可变性之前:

  1. 可变性是否必要?

    • 也许可以转换 → 返回新值
    • 也许可以使用构建器 → 以不可变方式构造
  2. 谁控制可变性?

    • 外部调用方 → &mut T
    • 内部逻辑 → 内部可变性
    • 并发访问 → 同步可变性
  3. 线程环境是什么?

    • 单线程 → Cell/RefCell
    • 多线程 → Mutex/RwLock/Atomic

向上追溯 ↑

当可变性冲突持续出现时:

E0499/E0502 (borrow conflicts)
    ↑ Ask: Is the data structure designed correctly?
    ↑ Check: m09-domain (should data be split?)
    ↑ Check: m07-concurrency (is async involved?)
持续出现的错误追溯到问题
反复发生借用冲突m09-domain是否应该重构数据?
async 中使用 RefCellm07-concurrency是否需要 Send/Sync?
Mutex 死锁m07-concurrency锁的设计是否合适?

向下追溯 ↓

从设计到实现:

"Need mutable access from &self"
    ↓ T: Copy → Cell<T>
    ↓ T: !Copy → RefCell<T>

"Need thread-safe mutation"
    ↓ Simple counters → AtomicXxx
    ↓ Complex data → Mutex<T> or RwLock<T>

"Need shared mutable state"
    ↓ Single-thread: Rc<RefCell<T>>
    ↓ Multi-thread: Arc<Mutex<T>>

借用规则

At any time, you can have EITHER:
├─ Multiple &T (immutable borrows)
└─ OR one &mut T (mutable borrow)

Never both simultaneously.

快速参考

模式线程安全运行时开销适用场景
&mut T不适用零独占可变访问
Cell<T>否零Copy 类型,不需要引用
RefCell<T>否运行时检查非 Copy 类型,需要运行时借用
Mutex<T>是锁竞争线程安全的可变性
RwLock<T>是锁竞争多读者、少写者
Atomic*是极小简单类型(bool、usize)

错误代码参考

错误原因快速修复
E0596将不可变借用为可变添加 mut 或重新设计
E0499多个可变借用重构代码流程
E0502存在 & 时使用 &mut分隔借用作用域

内部可变性决策

场景选择
T: Copy,单线程Cell<T>
T: !Copy,单线程RefCell<T>
T: Copy,多线程AtomicXxx
T: !Copy,多线程Mutex<T> 或 RwLock<T>
多线程、读操作频繁RwLock<T>
简单标志/计数器AtomicBool、AtomicUsize

反模式

反模式不足之处更好的做法
到处使用 RefCell运行时 panic明确所有权设计
单线程场景使用 Mutex不必要的开销RefCell
忽略 RefCell panic难以调试处理或重构
在热点循环中加锁严重影响性能批量操作

相关技能

场景参见
智能指针选择m02-resource
线程安全m07-concurrency
数据结构设计m09-domain
反模式m15-anti-pattern

评论

支持 Markdown