Skip to content

Commit 8d02b33

Browse files
committed
🤖📝AI: 更新 12.2 借用.md,补充借用指针与编译期检查的说明
1 parent c033e9b commit 8d02b33

1 file changed

Lines changed: 32 additions & 17 deletions

File tree

docs/第 12 章 借用和生命周期/12.2 借用.md

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,28 @@
33
变量对其管理的内存拥有所有权。借用就是一个值的所有权在不发生转移的情况下,借给其他变量使用。
44

55
在 Rust 中,当你“借用”(borrowing)一个值时,你实际上是在创建一个指向该值的引用。
6-
要使用借用,需要先使用引用语法:`&` 创建只读借用,`&mut` 创建可读写借用。
6+
要使用借用,需要先使用引用语法:`&` 创建只读借用(不可变引用)`&mut` 创建可读写借用(可变引用)
77
创建的引用只是拥有临时的使用权,而没有所有权。
88

99
因此,引用和借用虽然在术语上有所不同,但在实际使用中,它们描述的是同一个动作或状态:即一个值被另一个变量通过引用(或说“借用”)来访问。
1010

11-
==借用指针与普通指针的内部数据是一模一样的,唯一的区别是语义层面上的。它的作用是告诉编译器,它对指向的这块内存区域没有所有权。==
11+
==Rust 的引用(借用指针)在编译后与底层机器指针(如 C 语言的指针)在内存表示上是一致的,唯一区别是 Rust 编译器通过借用检查器对其进行静态安全检查,确保引用始终有效且符合所有权规则。==
12+
13+
### Rust 借用的核心规则
14+
15+
在使用借用时,必须遵守以下核心规则(由编译器强制检查):
16+
17+
1. **同一时间**,你只能拥有:
18+
- 一个可变引用(`&mut T`),或
19+
- 任意多个不可变引用(`&T`),但不能同时拥有可变引用
20+
2. **所有引用必须有效**:引用的生命周期不能超过其指向值的生命周期(即不能悬垂)
1221

1322
示例如下:
1423

1524
```rust
1625
fn foo(v: &Vec<i32>) {
17-
v.push(5);
26+
27+
v.push(5); // 错误:尝试通过不可变引用调用需要可变引用的方法
1828
}
1929

2030
fn main() {
@@ -34,20 +44,20 @@ pub fn push(&mut self, value: T)
3444
它要求 self 参数是一个 `&mut Self` 类型。而我们给 `foo` 传递的参数是 `&Vec` 类型,因此会报错。修复方式如下:
3545

3646
```rust
37-
// 我们需要“可变的”借用指针,因此函数签名需要改变
47+
// 需要接收可变引用参数
3848
fn foo(v: &mut Vec<i32>) {
39-
v.push(5);
49+
v.push(5); // 正确:通过可变引用修改 Vec
4050
}
4151

4252
fn main() {
43-
// 我们需要这个动态数组本身是“可变的”,才能获得它的“可变借用指针”
53+
// 1. 变量本身必须声明为可变(允许修改其内容)
4454
let mut v = vec![];
4555

46-
// 在函数调用的时候,同时也要显示获取它的“可变借用指针”
56+
// 2. 调用时获取可变引用
4757
foo(&mut v);
4858

49-
// 打印结果,可以看到 v 已经被改变
50-
println!("{:?}", v);
59+
// 打印结果,v 已被修改
60+
println!("{:?}", v); // 输出:[5]
5161
}
5262
```
5363

@@ -58,21 +68,26 @@ fn main() {
5868

5969
```rust
6070
fn main() {
61-
let mut var = 0_i32;
71+
let mut var = 0_i32; // var 是可变变量(可重新赋值)
72+
6273
{
63-
let p1 = &mut var; // p1 指针本身不能被重新绑定,我们可以通过 p1 改变变量 var 的值
64-
*p1 = 1;
74+
let p1 = &mut var; // p1 是不可变变量(不能重新赋值),但指向可变内容
75+
*p1 = 1; // 可以通过 p1 修改 var 的值
76+
// p1 = &mut 42; // 错误:p1 变量本身不可变,不能重新赋值
6577
}
78+
6679
{
6780
let temp = 2_i32;
68-
let mut p2 = &var; // 我们不能通过 p2 改变变量 var 的值,但 p2 指针本身指向的位置可以被改变
69-
p2 = &temp;
81+
let mut p2 = &var; // p2 是可变变量(可以重新赋值),但指向不可变内容
82+
// *p2 = 3; // 错误:p2 是不可变引用,不能修改指向内容
83+
p2 = &temp; // 正确:p2 变量本身可变,可以重新指向其他值
7084
}
85+
7186
{
7287
let mut temp = 3_i32;
73-
let mut p3 = &mut var; // 我们既可以通过 p3 改变变量 var 的值,而且 p3 指针本身指向的位置也可以改变
74-
*p3 = 3;
75-
p3 = &mut temp;
88+
let mut p3 = &mut var; // p3 是可变变量(可重新赋值),且指向可变内容
89+
*p3 = 3; // 可以修改指向内容
90+
p3 = &mut temp; // 可以重新指向其他可变内容
7691
}
7792
}
7893
```

0 commit comments

Comments
 (0)