Rust为确保程序在运行时不会出现数据竞争和其他内存安全,在使用引用时有很多规则,我在第一眼看到这些规则时也是有些头大,看了一段时间后才有了一些自己的一些理解。在这里对一些官方的术语和借用规则进行解释和记录。
&T
)。&mut T
)。上面为官方的解释,难理解的问题出现在这个同一时间,怎么才算同一时间。其实这里说的同一时间时指同一生命周期内。
同一时间内可以有多个不可变引用(&T)。即在同一个范围的生命周期内,可以包含多个不可变的引用。
------------------------------- |不可变引用A | |其它不可变引用 | |使用不可变引用A --------------------------------
如上图, 在不可变引用A的作用生命周期内,可以创建和使用多个不可变引用。实例代码:
let A = 1;
//不可变引用a
let a = &A;
//其它不可变引用
let b = &A;
//....
//使用不可变引用a
println!("{}", &a);
同一时间只能有一个可变引用(&mut T
)。即在同一个生命周期内只能有一个可变引用。
------------------------------------- //可变引用A // //周期内不能包含A的不可变引用 // //使用可变引用A ------------------------------------ 或者 ------------------------------------ //不可变引用A // //任何A的可变引用 // //使用不可变引用A -------------------------------------
如上图,在可变引用A的生命周期内,不能包含A的任何不可变引用。或者在不可变引用A的生命周期内不能包含任何可变A的可变引用
第一种情况:
let mut A = 1;
//可变引用a
let a = &mut A;
//其它不可变引用
let b = &A;
//....
//使用可变引用a
println!("{}", &a);
第二种情况:
let mut A = 1;
//不可变引用a
let a = &A;
//其它可变引用
let b = &mut A;
//....
//使用不可变引用a
println!("{}", &a);
不可变引用和可变引用不能同时存在。
其实可以理解为对第二条规则的总结,不能同时存在即在同一个生命周期内不能同时存在对A的不可变引用和可变引用。
注:对引用解引用即获取该引用的数据对象,如果再次引用即为借引用。这里需要注意对任何解引用的借引用都为不可变引用。
如下:
let mut A = 1;
//可变引用a
let a = &mut A;
//引用b为不可变引用
let b = & *a; //借引用a
这里a为可变引用,b借引用a,但是b为不可变引用。生命周期内同样需要满足上述借用规则。
Rust的借用规则虽然初看起来复杂,但通过合理组织代码结构和生命周期,可以有效地防止数据竞争和内存错误。理解“同一生命周期”的概念,以及如何在该生命周期内管理不可变和可变引用的使用,是掌握Rust借用系统的关键。这不仅提升了代码的安全性,也为编写高效的并发程序奠定了基础。随着对Rust的深入学习和实践,这些规则将逐渐成为编写稳健代码的自然习惯。