所有权
规则
- 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}
