【Rust】所有权、引用、借用
所有权
所有权的规则 1. Rust 中的每一个值都有一个被称为其 所有者(owner)的变量。 2. 值在任一时刻有且只有一个所有者。 3. 当所有者(变量)离开作用域,这个值将被丢弃。
Rust 采取了一个不同的策略:内存在拥有它的变量离开作用域后就被自动释放
变量与数据交互
方式(一):移动,转移所有权
let s1 = String::from("hello");
let s2 = s1;
// s1 不能再用
方式(二):克隆
let s1 = String::from("hello");
let s2 = s1.clone();
// s1,s2都可用
栈上的数据:复制
实现了Copy trait 整数、布尔、浮点、字符、元组
向函数传递值可能会移动或复制,移动时所有权会转移,复制不会转移
返回值也可以转移所有权
let mut s1 = String::from("hello");
s1 = take(s1);// 转移所有权到函数
println!("{}",s1);
fn take(s: String) -> String {
s// 返回所有权
}
引用
&符号是引用,*符号是解引用
创建一个引用的行为称为 借用(borrowing)
不可变引用
let s = String::from("hello");// 不可变变量
let len = calculate_length(&s);// &s是指向s的引用,但是并不拥有它
fn calculate_length(s: &String) -> usize {// 不可变引用参数
s.len()
}
可变引用
let mut s = String::from("hello");// 可变变量
change(&mut s);
fn change(s: &mut String) {// 可变引用参数
s.push_str(", world");
}
限制:在同一时间只能有一个对某一特定数据的可变引用
// 情况一
let mut s = String::from("hello");// 可变变量
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);// 报错 不能在同一时间多次将 s 作为可变变量借用
// 情况二
let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
let r3 = &mut s; // 大问题 不能在拥有不可变引用的同时拥有可变引用
println!("{}, {}, and {}", r1, r2, r3);
// 情况三
let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
println!("{} and {}", r1, r2);// 不可变引用 r1 和 r2 的作用域在 println! 最后一次使用之后结束
// 此位置之后 r1 和 r2 不再使用
let r3 = &mut s; // 没问题
println!("{}", r3);
这个限制的好处是 Rust 可以在编译时就避免数据竞争。
数据竞争(data race)类似于竞态条件,它可由这三个行为造成:
两个或更多指针同时访问同一数据。
至少有一个指针被用来写入数据。
没有同步数据访问的机制。
引用的规则
让我们概括一下之前对引用的讨论:
在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
引用必须总是有效的。
借用
创建一个引用的行为称为 借用(borrowing)

浙公网安备 33010602011771号