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
1625fn foo (v : & Vec <i32 >) {
17- v . push (5 );
26+
27+ v . push (5 ); // 错误:尝试通过不可变引用调用需要可变引用的方法
1828}
1929
2030fn main () {
@@ -34,20 +44,20 @@ pub fn push(&mut self, value: T)
3444它要求 self 参数是一个 `& mut Self ` 类型。而我们给 `foo ` 传递的参数是 `& Vec ` 类型,因此会报错。修复方式如下:
3545
3646```rust
37- // 我们需要“可变的”借用指针,因此函数签名需要改变
47+ // 需要接收可变引用参数
3848fn foo (v : & mut Vec <i32 >) {
39- v . push (5 );
49+ v . push (5 ); // 正确:通过可变引用修改 Vec
4050}
4151
4252fn 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
6070fn 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