内存管理
一般来讲,所有的程序都需要管理自己在运行时使用的计算机内存空间。
-
某些使用垃圾回收机制的语言会在运行时定期检查并回收那些没有被继续使用的内存;Java、Python、JS
-
而在另外一些语言中,程序员需要手动地分配和释放内存。C++
-
Rust采用了与众不同的第三种方式:它使用包含特定规则的所有权系统来管理内存,这套规则允许编译器在编译过程中执行检查工作,而不会产生任何的运行时开销。
所有权规则
- Rust 中的每一个值都有一个对应的变量作为他的 所有者
- 在同一时间内,值有且只有一个所有者
- 当所有者离开自己的作用域,它持有的值就会被释放掉
{ // 变量s 未定义,不可用
let s = "name"; // 可用
} // 作用域在这里结束,变量s 再次不可用; (Rust会在作用域结束时调用 drop函数 来释放内存)
所有权是针对于值(赋值操作就是所有权的转移过程)
fn main() {
let s1 = return_value(); // 函数return_value 将其返回值 移动 至s1 ===> 函数return_value返回值 的所有权 转移给变量s1
let s2 = String::from("hello"); // s2 进入作用域
let s3 = new_s2(s2); // s2 被移动至 new_s2函数(此时 s2已经无法访问),函数new_s2的返回值又被移动到 s3
println!("val: {}", s2); // 访问s2 编译时会报错
println!("val: {},{}", s1, s3);
}
fn return_value() -> u8 {
let abc: (i32, f32, u8) = (500, 2.0, 200);
let (a, b, c) = abc;
let a1 = abc.0;
let b1 = abc.1;
let c1 = abc.2;
abc.2
}
fn new_s2(s2: String) -> String {
s2
}
移动(move)
思考变量s1、s2,在内存中的数据结构是怎样的?
let s1 = String::from("hello");
let s2 = s1;
- 变量名s1、s2 存储在栈内存
- 对应值 存储在堆内存
- 当 s1 将其 对应值 的所有权转移给 s2后,Rust将不再视 s1 为有效的变量(可以理解为 移动 ,不同于其他语言中的 浅拷贝、深拷贝)