第3章 所有权法庭


第 3 章 · 所有权法庭

本章要回答的三个问题:值为什么只能有一个所有者?借用与引用的权限边界在哪里?生命周期标注到底在声明什么?

为什么会有这一章

第 1 章的三份内存事故卷宗在这里正式开庭。所有权系统是 Rust 的根本法:它决定每块堆内存何时释放(所有权)、谁能访问(借用)、访问权何时失效(生命周期)。绝大多数"Rust 太难"的抱怨,本质是没把这三条法条当成一个体系来理解。本章按庭审顺序走:先立产权,再发旁听证,最后核验证词有效期。

读完能解决什么

  • 面对移动语义报错,能说出哪个变量在何时持有所有权;
  • 记住"一个可变或任意多个不可变"的借用铁律并主动规避 E0502;
  • 读懂常见生命周期标注,并在编译器提示时正确补上。

各节怎么分工

节 回答哪个问题 关键产出
3.1 所有权三铁律 内存归谁、何时释放 移动与克隆的判断流程
3.2 借用与引用 不转移产权如何访问 借用铁律与三类高频案件
3.3 生命周期 引用凭什么不悬垂 标注语法与省略规则

先决条件

  • 第 2 章的作用域、mut 概念;
  • 对栈与堆的内存模型有基本印象即可,本章会即用即讲。

往下走到哪

所有权判例贯穿后续所有章节:第 5 章Trait 对象的生存期、第 8 章跨线程的产权移交,都是本章法条在新辖区的适用。

本章判例速查

三堂庭审的结论可以压缩成一张口袋卡,遇到报错先对号,再回对应节复庭。

报错 案情一句话 对应节
E0382 值已移动却还在用 3.1 移动语义
E0388 部分移动后整体再用 3.1 部分移动
E0502 读写借用区间重叠 3.2 借用铁律
E0499 可变借用出现两次 3.2 借用铁律
E0506/E0507 想把值移出借用 3.2 借用铁律
E0597 引用活得比数据久 3.3 生命周期
E0106 缺生命周期标注 3.3 生命周期

复习路径建议

本章不宜一次性读完。3.1 与 3.2 可以连读,因为移动与借用互为镜像——一个是产权移交,一个是产权出借;3.3 建议隔一天再开,生命周期引入了新的符号系统,混在一起容易把 'a 误解为某种类型参数。自测方案:找三段自己以前写的代码(或任何开源片段),逐行标注每个 String 的产权归属与每个引用的存活区间,标注不出来的一行,就是需要回庭的那一节。

向后判例的伏笔

本章立的三条法在第 5 章遇到 trait 对象时会出现新条款——Box<dyn Trait> 里藏着一个默认 'static 约束;在第 8 章跨线程场景下升级为 Send 与 Sync 两大检查。到那时回看本章会发现,所有权、借用、生命周期其实是同一条原则的三次适用:一切访问权限都必须能被静态证明。把这句话记住,Rust 的难点就从"规则多"变成"规则少而执法严"。

三条法的一句话背诵版

产权唯一:值只有一个所有者,赋值即移交。访问凭票:一写或多读,票的有效期是控制流区间而非文本顺序。证词有期:引用不得活得过数据,标注只约束不续命。三句话写进便签,遇到报错先背一遍再读报错,多数时候方向自动浮现。

三道自测题

一问:let v = vec![1,2,3]; let w = v; 之后 v 还能用吗,为什么?答:不能,Vec 持堆缓冲属 Move,E0382 候审。二问:函数签名 fn f(s: &mut String) 与 fn f(s: String) 对调用方的区别?答:前者租借可写权限、用后收回,后者索取产权、交出不返。三问:为什么 &'static str 可以从任何函数返回,而局部 String 的引用不行?答:字面量存于二进制只读区、活满全程,局部值随栈帧销毁。三题全对再进第 4 章,数据结构一章不过是本章法条在更大卷宗上的适用。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U