这就引出了我们的下一个痛点:
如果我只是想让你看一眼我的礼物(读取数据),而不是送给你(移交所有权),也没必要专门去复印一份(Clone),该怎么办?
在 Rust 里,这叫 借用 (Borrowing)。 我们会用到一个符号:&。
前端视角的类比
在 JavaScript 里,当你把对象传给函数时,默认就是传引用(你可以修改原对象)。 但在 Rust 里:
- 直接传值 = 移交所有权 (Move) (变量这之后就废了)。
- 传 & = 借用 (Borrow) (只是借你看,看完还我)。
来看看这个例子:
1 | |
发现了吗?我们只做了两个微小的改动:
- 传参时加了
&:&my_gift - 接收类型加了
&:&String
🧠 随堂小测验
借用虽然好,但别忘了 Rust 的第一章:默认不可变。 当你使用 &my_gift 借出数据时,默认是只读的(Read-only)。借书的人不能在书上乱涂乱画。
假设我想写一个函数,不仅要借用变量,还要修改它(比如给字符串后面追加内容)。
结合我们在第一章学到的知识(关于如何让变量可变),你觉得应该怎么组合这两个概念?
猜猜看: 如果 &String 是“不可变引用”,那么 “可变引用” (Mutable Reference) 应该怎么写?
A. mut &String B. &mut String C. &String mut
🎉 答案就是 B: &mut String
你现在的 Rust 语感已经很好了。这一章我们把最难啃的骨头啃下来了,为了巩固一下,我们来看一个完整的“可变借用”例子。
可变借用实战
这里有一个常见的误区:要想借出去修改,首先原主自己得有修改权。
- 变量本身必须是
mut的。 - 传递的时候要传
&mut。 - 接收的时候要接
&mut。
1 | |
⚠️ 借用规则的“高压线” (The Golden Rules)
虽然 &mut 很强大,但 Rust 编译器是一个极其严格的管理员。为了防止数据竞争 (Data Race)(也就是前端常遇到的:我在渲染列表,结果后台把列表清空了,导致页面白屏崩溃),Rust 定下了两条铁律:
在任意时刻,针对同一个数据,你只能满足以下二者之一:
- 拥有 任意数量 的不可变引用 (&T)
- 拥有 仅仅一个 可变引用 (&mut T)
❌ 绝对不能同时存在!
1 | |
这个报错是很多 Rust 新手的噩梦,但它的初衷是保护你的程序不出现诡异的 Bug。
🎉 第二章通关!
目前为止,我们已经搞定了:
- 变量与类型:
let,mut,i32vsu8。 - 内存安全: 所有权 (
Move),克隆 (Clone),不可变借用 (&),可变借用 (&mut)。
你现在已经掌握了 Rust 语法的 60% 核心难度!剩下的很多是应用层面的东西。