Rust 第一天:所有权到底在解决什么

学一门新技术,先在脑子里建立「问题地图」——它存在是为了解决什么?比「怎么写」重要。


第一天:撞上 ownership

之前写 JS/Python,从来没想过「这块内存是谁的」。

Rust 第一天就撞墙:编译器不让我编译,因为「这块内存的所有权不对」


先想清楚:所有权在解决什么

C/C++ 的内存问题,本质只有一个:

谁负责释放内存?

方案代表代价
手动管理C / malloc/free忘了 free → 内存泄漏;free 早了 → use-after-free
垃圾回收Java / Python / JS运行时开销;STW 暂停

Rust 选了第三条路:

编译时定死「谁拥有这块内存」,出作用域自动释放。

不是 GC,不是手动——是编译器帮你管


第一天的认知卡点

卡点 1:「移动」到底在干什么?

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

我第一反应是:「为什么不能复制?」

后来想清楚:复制是有代价的(堆内存拷贝)。Rust 默认不复制,强制你「想清楚要不要复制」——要复制就显式写 .clone()

认知:Rust 不是在「限制你」,是在「逼你 upfront 想清楚代价」。


卡点 2:借用为什么要有生命周期?

fn longest(x: &str, y: &str) -> &str {
    if x.len() > y.len() { x } else { y }
}
// 编译错误:返回值生命周期不明确

第一反应是:「编译器怎么这么笨,x 和 y 都是传进来的,返回哪个不就行了吗?」

后来想清楚:返回的引用,到底指向谁的內存? 如果 x 出作用域了,返回的引用就悬空了。

认知:生命周期标注不是在「告诉编译器怎么跑」,是在「逼你把依赖关系写清楚」。


第一天结束时的认知地图

R}ust{C/C++线++upfronWtebAssembly

还没想清楚的

  1. 「生命周期」和「泛型」放在一起时(lifetime bounds),为什么需要写 'a: 'b 这种语法?它在约束什么?
  2. Rc/Arc 为什么是「引用计数」而不是「所有权转移」?什么场景下需要它们?
  3. Rust 的「所有权」和 JS 的「闭包捕获」有没有本质联系?(都是「这段内存归谁」的问题)

(这些问题不急着答案——先让它们在脑子里转几天。)


这篇笔记的「道」

学一门新技术,不要急着「跑起来」。 先花一天,把「它存在是为了解决什么」想清楚。 剩下的,查文档就行。