04所有权·2引用与借用
介绍rust的一个特性:所有权之引用与借用
引用[20230105]
(一).定义
允许你引用某个值而不取得其所有权
1
2
3
4
5
6
7
8
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);//&s1以引用的方式(所有权未转移)传递给数calculate_length
println!("The length of '{}' is {}.", s1, len);//这里s1可以继续使用
}
fn calculate_length(s: &String) -> usize {//s是对string的引用。上面数调用calculate_lengt(&s1)则,s借用s1变量
s.len()
}//s离开了作用域不会调用drop。因为它并不拥有引用值的所有权,
引用示意图
(二).引用的可变性和不可变性
1.引用的不可变性
引用和变量一样默认是不可变的
1
2
3
4
5
6
7
fn main() {
let s = String::from("hello");
change(&s);
}
fn change(some_string: &String) {
some_string.push_str(", world");//cannot borrow `*some_string` as mutable, as it is behind a `&` reference
}
2.可变引用
(1).声明语法:xx: &mut TYPE
1
2
3
4
5
6
7
fn main() {
let s = String::from("hello");
change(&s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");//现在可正常编译了
}
(2).可变引用的限制
- 在特定作用域内的变量只能有一个可变引用
1
2
3
4
5
6
fn main() {
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;//cannot borrow `s` as mutable more than once at a time
println!("{}, {}", r1, r2);
}
- 限制的作用:编译期防止数据竞争(data race)。
- data race成立的三个条件:
- 两个以上的指针同时访问同一个数据
- 至少有一个指针用于写入数据
- 没有同步的机制访问数据
- data race成立的三个条件:
- 可通过创建新作用域,实现非同时多个可变引用
1
2
3
4
5
6
7
fn main() {
let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1 在这里离开了作用域,所以我们完全可以创建一个新的引用
let r2 = &mut s;
}
(3)一个变量不可同时拥有可变引用和不可变引用
1
2
3
4
5
6
7
8
9
10
//不可变引用的用户可不希望在他们的眼皮底下值就被意外的改变了!
//然而,多个不可变引用是可以的,因为没有哪个只能读取数据的人有能力影响其他人读取到的数据。
fn main() {
let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
let r3 = &mut s; //cannot borrow `s` as mutable because it is also borrowed as immutable
println!("{}, {}, and {}", r1, r2, r3);
}
(三).悬垂引用(Dangling References)
悬垂指针是其指向的内存可能已经被分配给其它持有者
rust可避免悬空引用
1
2
3
4
5
6
7
8
9
fn main() {
let reference_to_nothing = dangle();//error[E0106]: missing lifetime specifier
}
fn dangle() -> &String {
let s = String::from("hello");
&s
}//由于dangle返回的是一个引用(没有发生所有权转移),所以s离开作用域并被丢弃。
//当你拥有一些数据的引用,编译器确保数据不会在其引用之前离开作用域。
(四).读记引用的规则
- 在任意给定时间、作用域内,要么只有一个 可变引用,要么只有1个或多个不可变引用。不允许同时 存在 可变和 不可变引用
- 引用必须一直有效(指悬垂引用)
借用[20230105]
将创建一个引用的行为称为 借用(borrowing)(如上:把引用作为函数参数这个行为叫借用)
This post is licensed under CC BY 4.0 by the author.