所有权
规则
- Rust 中的每一个值都有一个被称为其 所有者(owner)的变量。
- 值有且只有一个所有者。
- 当所有者(变量)离开作用域,这个值将被丢弃。
移动(move)语义
如果一个类型拥有 Copy trait,一个旧的变量在将其赋值给其他变量后仍然可用。Rust 不允许自身或其任何部分实现了 Drop trait 的类型使用 Copy trait。如果我们对其值离开作用域时需要特殊处理的类型使用 Copy 注解,将会出现一个编译时错误。{
let s1 = String::from("haha");
// s1无效了
let s2 = s1;
//基本类型(编译器已知在内存中大小类型)可以直接拷贝赋值
let x = 5;
let y = x;
}//自动调用drop()
这些类型默认实现Copy trait:整型、布尔、浮点数、字符、包含Copy trait类型的元组。
深拷贝let s1 = String::from("haha");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);
块结尾自动调用drop函数释放内存。
RAII(Resource Acquisition Is Initialization 资源获取即初始化)
所有权与函数
fn main() {
let s = String::from("haha");
//所有权转移到函数内部,外部不能再使用
take_ownership(s);
//Copy类型,外面还可以使用
let x = 5;
make_copy(x);
}
fn take_ownership(s: String) {
println!("{}", s);
}
fn make_copy(x: i32) {
println!("{}", x);
}
返回值转移所有权
fn main() {
let s1 = give_ownership();
let s2 = String::from("hehe");
let (s3, len) = take_and_give_ownership(s2);
println!("{}", s1);
println!("{}, {}", s3, len);
}
fn take_and_give_ownership(s: String) -> (String, usize) {
let len = s.len();
(s, len)
}
fn give_ownership() -> String {
String::from("haha")
}
引用与借用
引用
fn main() {
let s = String::from("hehe");
//创建引用传递进去
let len = get_len(&s);
println!("{}, {}", s, len);
}
//函数以引用作为参数成为借用(borrowing)
fn get_len(s: &String) -> usize {
s.len()
}
可变引用
悬垂引用(Dangling References)
和悬垂指针类似,Rust会进行静态检查编译报错。下面代码s已经释放,&s会变成悬垂引用。
fn main() {
let r = dangle()
}
fn dangle() -> &String {
let s = String::from("haha");
&s
}