# 所有权(ownership)—— Rust 的核心功能之一
通常编程语言管理内存的方式主要有两种:1、依赖 GC 进行自动回收,如 Java 语言等;2、依赖代码编写者手动在合适的地方进行内存分配和回收,如 C、C++ 语言等。
Rust 则选择使用所有权机制来进行内存管理,这样避免 GC 带来的更多系统开销,以及需要手动进行内存管理的麻烦
# 所有权的三个基本规则
- Rust 中的每一个值都有一个被称为其所有者的变量
- 一个值在任一时刻只能有一个所有者
- 当所有者离开作用域时,其值将被丢弃
fn main() { // 作用域开始
let s = "hello"; // s进入作用域,开始有效
// 使用s
} //作用域结束,s不再有效,内存释放
# 变量与数据交互方式(一):移动
fn main() {
let s1 = String::from("hello"); // 在这里s1是字符串hello的所有者
let s2 = s1; // 从这里开始所有权发生了移动,由s1移动到了s2
// 此后s1不再有效,而s2可以继续使用
// println!("s1: {}, s2: {}", s1, s2); //这句代码会发生错误
}
# 变量与数据的交互方式(二):克隆
fn main() {
let s1 = String::from("hello"); // 在这里s1是字符串hello的所有者
let s2 = s1.clone(); // 产生一个字符串hello的拷贝,并且s2是这个新字符串的所有者
// 此时s1、s2均有效,可以继续使用
println!("s1: {}, s2: {}", s1, s2);
}
在 Rust 中对于编译时大小未知或不确定的数据都是存储在堆上的;而对于大小已知或确定的数据都是存储在栈上的。对于存储在栈上的数据,在进行赋值操作时,不会发生移动,而是会产生一个拷贝值,并将其绑定到新的变量上,因此原来的变量仍然有效;而对于存储在堆上的数据,在进行赋值操作时,会产生其存储在栈上的指针(指向堆内存空间的指针)的一个拷贝,并将其绑定到新的变量上,同时使原来的变量失效。