一、借用(引用)
不想转移所有权时,用引用 &T(不可变借用)或 &mut T(可变借用):
fn len(s: &String) -> usize { s.len() } // 借用在参数,不夺所有权
let mut s = String::from("hi");
let r = &mut s; // 可变借用
r.push_str("!");
二、借用规则(编译期检查)
| 允许情况 |
|---|
同一作用域内可同时存在多个 &T |
或只存在一个 &mut T |
| 两者不能同时存在(防数据竞争) |
三、生命周期
当函数返回引用时,编译器需要确认返回的引用有效,用 'a 标注:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
多数情况编译器能自动省略生命周期标注(省略规则),仅在返回引用歧义时才需手写。
借用 + 生命周期让 Rust 在编译期杜绝悬垂指针与数据竞争,这是它区别于 C++ 的关键。