fn main() {
// {}范围内的是变量的作用域
let x = 1;
{
let y = 2;
println!("y={}", y);
}
println!("x={}", x);
{
// [堆]所有权移动,s1的指针移动到了s2,s1被释放
let s1 = String::from("hello");
let s2 = s1;
println!("s2={}", s2);
//println!("s1={}",s1); // value borrowed here after move
}
{
// [堆]拷贝,让指针不移动
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s2={}", s2);
println!("s1={}", s1);
}
{
// [栈] 栈上的数据不会移动,只会被copy
let x = 1;
let y = x;
println!("x={}", x);
println!("y={}", y);
}
{
// 函数返回值的所有权
let s = gives_ownership();
println!("{}", s); // s 拥有了返回值的所有权,正常访问
}
}
fn gives_ownership() -> String {
let s = String::from("hello");
s // 返回 s 把所有权移交给调用者
}
小结:
- 作用域范围结束之后rust会隐式调用
drop()方法释放内存 - 指针移动之后,之前的数据就不能再访问了,也即所有权从一个变量移交到了另一个变量
- 栈上的数据赋值后还能继续访问,这是因为数据直接被copy了一份
- 常见的具有
copy trait的数据类型:所有整型,浮点型,布尔值,字符类型,元组
所有权的规则/定义:
- Rust中的每一个值都被绑定到一个变量上,该变量为该值的“所有者”(Owner)
- 在同一时间内,该值只会有一个所有者
- 当所有者(Owner)离开作用域时,Rust会自动调用
drop()函数释放该值所占用的内存
所有权的移动:当一个变量被赋值给另一个变量时,所有权也会随之移交给第二个变量,这称之为移动(Move)。这点于其他语言进行浅复制(shallow copy)有许些不同。这也同时防止了悬垂指针的出现。
综上所述,所有权(Ownership)的意义如下:所有权是rust中独特的内存管理特性之一,所有权提供了一种无需垃圾回收的,安全的内存管理方式,确保程序不会发生悬垂指针,以及避免内存二次释放的错误。