跳到主要内容

所有权

堆栈

栈,先进后出,速度快,编译时已知大小 堆,

所有权

1.Rust 中的每个值都有一个所有者。Rust 程序中的每个数据或“值”都归一个变量所有。这个变量就是它的所有者。

2.同一时间只能有一个所有者。只要赋值给了另一个变量,原来的变量就不再拥有这个值了。

    let s1 = String::from("hello");
let s2 = s1; // s1的所有权被转移到s2

println!("s1: {s1}"); // 这行会报错,因为s1不再拥有值
println!("s2: {s2}"); // 这行可以正常打印,因为s2现在拥有值

3.当所有者超出范围时,价值将会下降。当一个数据的所有权转移到一个局部变量上时,在这个局部变量的作用域之外,这个数据是无效的。

    {
let s = String::from("hello");
// s在这里有效
}
// s在这里无效,无法访问

copy

实现该接口的类型Copy通常是简单的标量类型,其数据完全存储在栈上。常见的例子包括:

所有整数类型(例如i32,u64) 布尔类型(bool) 浮点类型(例如,f64) 字符类型(char) 元组,如果它们只包含也实现了该接口的类型Copy。 关键在于,String它没有实现,Copy因为它管理的是堆分配的数据。

borrowing

借用是通过创建对某个值的引用来实现的。

什么是借贷?从本质上讲,借贷是指暂时使用某项价值而不取得所有权。 如何借用?您可以通过创建对某个值的引用来借用它。 引用的影响:当创建数据引用并将其传递给函数时,原始数据的所有权不会转移。原始所有者仍然保留控制权。

不可变引用 &T

不可变引用允许你读取数据但不能修改数据。不可变引用的关键规则是: 您可以同时拥有任意数量的指向同一数据的不可变引用。

    let s = String::from("hello");
let r1 = &s; // 不可变借用
let r2 = &s; // 另一个不可变借用
println!("r1: {}, r2: {}", r1, r2); // 可以同时使用多个不可变引用

可变引用 &mut T

可变引用允许您读取和写入(修改)它所指向的数据。要创建可变引用,必须使用mut关键字将原始数据声明为可变的。

可变引用的关键规则是:

在特定作用域内,任何时候都只能有一个对特定数据的可变引用。这条规则可以防止编译时出现数据竞争。

    let mut s = String::from("hello");
let r1 = &mut s; // 可变借用
// let r2 = &mut s; // 这行会报错,因为不能同时拥有多个可变引用
r1.push_str(", world!"); // 修改数据
println!("r1: {}", r1); // 可以使用可变引用

非词法生命周期 (NLL):需要注意的是,借用操作的作用域并不一定持续到定义它的整个词法块结束。相反,借用操作会持续到它最后一次被使用为止。这种称为非词法生命周期 (NLL) 的特性使得代码更加灵活。例如,在可变引用最后一次被使用后,你可以在同一个词法作用域内创建指向相同数据的另一个可变引用:

    let mut s = String::from("hello");
let r1 = &mut s; // 可变借用
r1.push_str(", world!"); // 修改数据
println!("r1: {}", r1); // 使用可变引用

// r1在这里不再被使用,所以我们可以创建另一个可变引用
let r2 = &mut s; // 另一个可变借用
r2.push_str(" Welcome to Rust!"); // 修改数据
println!("r2: {}", r2); // 使用新的可变引用

就是在创建了r2之后,r1就不再被使用了

可变与不可变引用的规则:两者不共存

任意数量的不可变引用(&T),或者

只能有一个可变引用(&mut T)。 两种类型的引用不能同时处于活动状态。这可以避免出现这样的情况:数据通过可变引用被修改,而代码的其他部分却期望数据通过不可变引用保持不变。

总结

总结一下 Rust 中借用机制的核心规则和优势:

1.借用允许通过引用暂时访问某个值,而无需取得所有权。 2.创建引用并不会转移数据的所有权。 3.引用可以是不可变的(&T),只允许读取访问;也可以是可变的(&mut T),允许读写访问。

对于特定范围内的任何给定数据,您可以: 1.任意数量的不可变引用,或者 2.只能有一个可变引用。 你不能同时对同一数据使用两种类型的引用。

引用的生命周期绝不能超过它所指向的数据。Rust 编译器强制执行此规则,以防止出现悬空引用。

📢 Share this article