借用与引用
引用(reference)允许在不取得 所有权 的前提下临时使用值。借用分 不可变 &T 与 可变 &mut T,编译器在编译期检查借用规则,避免数据竞争。
两条借用规则
- 任意时刻,要么存在任意多个
&T,要么存在唯一一个&mut T(不能与其它&T/&mut T重叠冲突)。 - 引用必须始终有效(不长于被借用的数据),由 生命周期 标注或推断保证。
不可变引用 &T
可同时存在多个只读借用,常用于函数参数「只读查看」:
fn len(s: &String) -> usize { s.len() }&str、&[T] 等切片引用见 数据类型。
可变引用 &mut T
独占写权限,可修改被指向的数据且无并发写(在同一执行线程内由规则保证)。
fn push_hello(v: &mut Vec<String>) {
v.push(String::from("hello"));
}悬垂引用
若引用指向的数据已被 drop 或已被 move,编译会失败。这是 生命周期 要解决的核心问题。
解引用与 Deref
- 运算符
*:对引用解引用到目标(或调用Deref/DerefMut)。 - 强制转换(deref coercion):如
&String→&str等方法参数处的便利规则。
与所有权协作的常见模式
- 「只读遍历」:
&T/&[T] - 「原地修改」:
&mut T - 「消费并返回新值」:直接传
T(move),或返回T(错误处理 里Result也常如此)