Rust入门-06-引用与借用
引用与借用
-
引用是一种数据类型
-
& 符号就是引用
- 允许使用值但不获取其所有权
-
解引用(dereferencing)
- 解引用运算符 *
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // &s1 创建了一个指向 s1 的引用,但不拥有s1
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize { //参数为&String,不是String
s.len()
} // s 离开了作用域。但因为它并不拥有引用值的所有权,所以什么也不会发生
-
s 为 s1 的引用,s 指向 s1 (指针?
![]()
借用(borrowing)
-
把引用作为函数参数的行为叫做借用
-
默认不允许修改引用的值
fn main() { let s = String::from("hello"); change(&s); } fn change(some_string: &String) { some_string.push_str(", world"); }该代码不能编译
可变引用
-
&mut string就为一个可变引用类型fn main() { let mut s = String::from("hello"); change(&mut s); } fn change(some_string: &mut String) { some_string.push_str(", world"); }该代码可以正常编译
-
限制:在同一时间,对于某一特定的数据,只能有一个可变引用
- 尝试创建两个可变引用的代码将会失败
let mut s = String::from("hello"); let r1 = &mut s; let r2 = &mut s; println!("{}, {}", r1, r2);该代码不能编译
-
这个限制的好处是 Rust 可以在编译时就避免数据竞争(出现数据竞争的情况时,rust在编译时就会报错
- 数据竞争(data race)类似于竞态条件,它可由这三个行为造成:
- 两个或更多指针同时访问同一数据
- 至少有一个指针被用来写入数据
- 没有同步数据访问的机制
- 数据竞争(data race)类似于竞态条件,它可由这三个行为造成:
-
可以创建新的作用域(通过大括号),以允许非同时拥有多个可变引用
let mut s = String::from("hello"); { let r1 = &mut s; } // r1 在这里离开了作用域,所以可以创建一个新的引用 r2 let r2 = &mut s; -
另一个限制:不可以同时有一个可变引用与一个不可变引用
- 但可以有多个不可变引用
let mut s = String::from("hello"); let r1 = &s; // 不可变引用 let r2 = &s; // 不可变引用 let r3 = &mut s; // 可变引用,不可以 println!("{}, {}, and {}", r1, r2, r3);该代码不可以编译
悬垂引用(Dangling References)
-
悬垂指针(dangling pointer),即一个指针引用了内存的某个地址,但这块内存可能已经事发并分配给其他人使用了
-
在 Rust 中编译器可以确保引用永远也不会变成悬垂状态
- 当你拥有一些数据的引用,编译器确保数据不会在其引用之前离开作用域。
fn main() { let reference_to_nothing = dangle(); } fn dangle() -> &String { let s = String::from("hello"); // s 在离开函数(离开作用域)后,就失效了 &s //但对 s 的引用 &s 作为返回值返回了 //即对 s 的引用 &s 就指向了一个被释放的内存地址 }该代码不可以编译
引用的规则(总结
- 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用
- 引用必须一直是有效的


浙公网安备 33010602011771号