BORROW & RETURN · 所有权 · 借用 · 生命周期 · 一门被你劝退过的语言

借还已登记

B O R R O W   &   R E T U R N

你大概试过不止一次。买过书、看过视频、跟着教程敲了 Hello World,然后信心满满写第一个真程序 —— 结果卡在一片红色的编译错误里:borrow of moved valuecannot borrow as mutabledoes not live long enough。你和编译器搏斗了一下午,把代码改得连自己都不认识,最后默默关掉了编辑器。「Rust 是好,但我可能不是那块料。」

我想告诉你:你不是学不会。你是每次都在同一堵墙前被弹回来。那堵墙叫借用检查器,而它背后只有一句话 —— 一个值,任何时刻,只有一个所有者;要么很多人一起读,要么一个人独自写,二者不可兼得。整门语言 —— 移动、借用、生命周期、String&strOptionResult、trait、Rc、async —— 都是这一句话的展开。

这本书换个走法:先陪你把那堵墙拆开看清楚,再从这一句话出发,把整门语言重新长一遍。招牌是一台真的借用检查器 —— 它就在网页里跑,你改一行代码,它当场重判,连那个玄学的「读完就放」(NLL)都对得上。你会亲眼看到:编译器不是在为难你,它是在替你把一整类 bug,挡在上线之前。

24
6
11个互动 Demo
1台你能当场折腾的借用检查器

为什么又是一本 Rust 书

市面上讲 Rust 的书不缺,官方那本《The Rust Programming Language》就写得极好。但它们大多有个共同的隐含假设:你会一路读下去。于是它们从语法开始,一节一节铺,等你读到借用检查器时,已经翻了一百页 —— 而你被劝退,恰恰就发生在那一页

这本书倒过来。它假设你已经被弹回来过,甚至不止一次。所以它第一件事不是教语法,而是陪你正面看那堵墙:你到底卡在哪、编译器为什么要这么凶、那些错误信息在替你挡什么。看清楚了,你会发现墙其实很薄 —— 薄到只有一句话。剩下的整门语言,都是从这句话里长出来的,一旦地基稳了,上面反而好走。

◆ 这本书的一句话

一个值,任何时刻,只有一个所有者。它可以被借出去 —— 但要么借给很多人一起读&共享,随便多少个),要么借给一个人独自写&mut 独占,只能有一个),两者不能同时。值离开作用域,就自动归还(drop)。

C 和 C++ 用二十年、无数次崩溃和安全漏洞才教会程序员小心的事,Rust 把它变成了一条编译期就查的规则。学 Rust 的痛,是把这门课一次性补完的痛。补完了,你写任何语言都会不一样。

招牌:一台真的借用检查器

别的书讲借用检查器,规则是印在纸上的,你得自己在脑子里模拟它怎么判。这本书的借用检查器是用 JavaScript 真写出来的,就嵌在网页里。它跟踪每个值的所有者、每一处活跃的借用、每一层作用域,报出和 rustc 同款的诊断:

  • &&mut 摆在一起 —— 它当场喊 E0502,告诉你「不能借为可变,因为同时被借为不可变」;
  • 移动一个值之后又用它 —— E0382「使用了已被移出的值」,还指给你看是哪一行把它移走的;
  • 让一个引用比它指向的值活得久 —— E0597「活得不够久」,配一张生命线图让你看清谁伸出了谁;
  • 甚至那个让所有人头疼的 NLL(读完就放) —— 你把一句 println! 挪个位置,同一段代码的判决就跟着变,它全跟你演出来。

正文里每一处「这里会报 EXXXX」的断言,都是这台引擎当场跑出来的,不是我写死的。你可以打开那个 Demo,把代码改成你自己的样子,看它怎么判。

这本书假设你已经会什么

写给这样的人

  • 能熟练写 Kotlin / Java / JS / TS / Python / Go 里的至少一门
  • 试过学 Rust,卡在借用检查器 / 生命周期,然后放弃了(至少一次)
  • 知道栈和堆大概是什么,但没真在意过谁在什么时候释放内存
  • 想要的是把墙拆开看懂,不是背下一堆「遇到 X 就写 Y」的口诀
  • 愿意在一台真检查器上动手改代码、看它报错

暂时不适合

  • 完全没写过代码 —— 这本书假设你有编程基础
  • 要的是完整的语言规范 / 标准库百科(那是官方文档的活)
  • 想直接上手 embedded / 内核 / async runtime 源码(先把地基走一遍)
  • 受不了「先接受约束,再谈自由」这种顺序 —— Rust 全书都是这个顺序
▶ 关于「跑代码」这件事

这本书不需要你装任何东西就能读。借用检查器、状态机、切片视图……都在网页里,Demo 就是它们本人,你可以只读、只玩。

但如果你想真的动手写(强烈建议),装一套工具链只要五分钟 —— 第 3 章会带你装好 rustupcargo,然后就忘了它,把注意力全放回语言本身。书里的 Rust 代码,语义都对得上真正的 rustc

怎么读

顺着读。这本书是有地基的:卷 I 陪你和那堵墙和解,卷 II 把地基(所有权)夯实 —— 这两卷是全书的命根子,慢慢读。地基稳了,卷 III 之后就是在上面盖房子:用类型消灭一整类 bug(Option / Result / trait),诚实地讲那些「一个所有者不够用」时的逃生口(Rc / RefCell / unsafe),把所有权规则原样搬到多线程(并发与 async),最后落到工程实践和从 Kotlin 迁移。

每一章末尾都有一节 「回流」:这一课在你熟悉的 Kotlin / Java / JS 里,对应着什么、又差在哪。那是你补完这门课,能换回真实世界的东西 —— 你会发现自己写别的语言时,也开始下意识地想「这个值现在归谁、谁能改它」。