スキル一覧に戻る
huiali

rust-ownership

by huiali

An AI expert capability layer for Rust engineering practices, centered on modular skill orchestration and collaborative execution chains. It turns Rust’s core knowledge structures into callable reasoning and decision units, enabling diagnosis, design, and optimization in complex real-world scenarios.

1🍴 1📅 2026年1月25日
GitHubで見るManusで実行

SKILL.md


name: rust-ownership description: "所有权、借用、生命周期专家。处理 E0382, E0597, E0506, E0507, E0515, E0716, E0106 等错误。触发词:ownership, borrow, lifetime, move, clone, Copy, 所有权, 借用, 生命周期" globs: ["**/*.rs"]

所有权与生命周期专家

核心信条

每个值都有一个明确的主人

这是 Rust 最独特的设计。理解所有权,你就理解了 Rust 的一半。


常见问题模式

模式 1:移动后的使用

let s1 = String::from("hello");
let s2 = s1;
// println!("{}", s1); // 编译错误!

问题本质:s1 的所有权转移给了 s2,s1 不再有效

解决方案

  • 如果需要两个副本 → clone()
  • 如果只需要读 → 传递引用 &s1
  • 如果 s2 只是临时 → 考虑重新设计

模式 2:借用冲突

let mut s = String::from("hello");
let r1 = &s;
let r2 = &mut s; // 冲突!
// println!("{}", r1);

问题本质:不可变借用和可变借用同时存在

解决方案

  • 确保可变借用使用完毕后再创建新的借用
  • 重新组织代码结构

模式 3:生命周期不匹配

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() { s1 } else { s2 }
}

问题本质:返回值生命周期必须和输入之一关联

解决关键

  1. 明确每个引用的生命周期
  2. 用命名生命周期表达关系
  3. 优先返回 owned 类型

我的思考流程

1. 谁拥有数据?

情况所有者
函数参数调用者拥有
函数内部变量函数拥有(返回时销毁)
结构体字段结构体实例拥有
Arc<T>多个共享所有者

2. 借用合理吗?

操作借用类型注意事项
只读操作&T可多个同时存在
需要修改&mut T同时只能有一个
借用期间原值会被修改吗?如果会,问题就在这里

3. 能避免生命周期吗?

返回 String 而不是 &str
    ↓
使用 owned 集合而不是切片
    ↓
用 Arc/Rc 共享所有权
    ↓
生命周期不是必须品

智能指针选择

场景选择原因
堆分配单个值Box<T>简单直接
单线程共享引用计数Rc<T>轻量级
多线程共享引用计数Arc<T>原子操作
需要运行时借用检查RefCell<T>单线程内部可变性
多线程内部可变性Mutex<T>RwLock<T>线程安全

反模式警示

反模式问题正确做法
.clone() 到处都是隐藏所有权问题思考真正的所有权需求
'static 用于所有地方过于宽松且不精确使用实际需要的生命周期
Box::leak() 泄漏内存内存浪费使用正确的生命周期管理
与借用检查器对抗给自己挖坑理解并配合编译器的设计

实践建议

新手常见困惑

  1. "什么时候该用引用,什么时候该用所有权?"

    • 函数参数用引用(除非需要消耗)
    • 函数返回值用引用(如果 caller 不需要所有权)
    • 存储时考虑生命周期复杂度
  2. "生命周期注解到底怎么加?"

    • 大多数情况编译器能推断
    • 结构体、trait impl、方法返回引用时需要显式标注
    • 生命周期名称要有意义,比如 'connection'file
  3. "为什么这个借用不工作?"

    • 可变借用期间原值不可访问
    • 检查借用的作用域范围
    • 考虑是否需要重新组织代码结构

错误码速查表

错误码含义不要说要问
E0382值被移动后使用"clone it"谁应该拥有这个数据?
E0597生命周期太短"extend lifetime"作用域边界正确吗?
E0506借用未结束就被修改"end borrow first"变异应该在哪里发生?
E0507从引用 move 出数据"clone before move"为什么要从引用移动?
E0515返回非 owned 数据"return owned"调用者应该拥有数据吗?
E0716临时值生命周期不足"bind to variable"为什么这个是临时的?
E0106生命周期参数缺失"add 'a"生命周期关系是什么?

思考过程

遇到所有权问题时,按以下步骤思考:

  1. 这个数据在领域中的角色是什么?

    • 实体(有唯一标识)→ owned
    • 值对象(可互换)→ clone/copy 可以
    • 临时计算结果 → 考虑重构
  2. 所有权设计是有意为之还是意外?

    • 有意 → 在约束内工作
    • 意外 → 考虑重新设计
  3. 修复症状还是重新设计?

    • 如果尝试 3 次仍失败 → 升级到设计层面

向上追踪(Trace Up)

当所有权错误持续时,追踪到设计层面:

E0382 (moved value)
    ↑ 问:什么设计选择导致了这种所有权模式?
    ↑ 查:这是实体还是值对象?
    ↑ 查:是否有其他约束?

持续 E0382 → rust-resource:应该用 Arc/Rc 共享吗?
持续 E0597 → rust-type-driven:作用域边界正确吗?
E0506/E0507 → rust-mutability:应该用内部可变性吗?

向下实现(Trace Down)

从设计决策到实现:

"数据需要不可变共享"
    ↓ 多线程:Arc<T>
    ↓ 单线程:Rc<T>

"数据需要独占所有权"
    ↓ 返回 owned 值

"数据只是临时使用"
    ↓ 在作用域内使用引用

"需要在函数间传递数据"
    ↓ 考虑生命周期或返回 owned

スコア

総合スコア

70/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です