为什么Rust中通过指针间接获取同一值的多个可变引用是合法的
Rust可变引用重借用规则说明
你对代码的认知存在偏差,两段代码的本质区别是前者触发了Rust的**可变引用重借用(Reborrow)**规则,后者是直接创建两个平级的独立可变引用,违反了所有权核心约束,具体逻辑如下:
核心规则前提
Rust所有权模型对可变引用的核心约束是:同一时间,同一个值只能存在一个活跃的可变引用,这里的关键是「活跃状态」和「引用从属关系」两个判定条件。
第一段代码合法的原因
let mut x: i32 = 1; let ref_x = &mut x; let refref_x = &mut *ref_x; *refref_x = 2; *ref_x = 3;
第三行的&mut *ref_x不是直接从x借出引用,而是从已有的可变引用ref_x身上重新借出一个新的可变引用,二者是从属关系而非平级的独立引用:
- 重借用得到的
refref_x生命周期被严格限制为不能超过原引用ref_x的生命周期 - 在
refref_x的活跃周期内,原引用ref_x会被临时冻结,无法使用 - 代码中
*refref_x = 2是refref_x的最后一次使用,执行完后它的生命周期就结束了,原引用ref_x恢复可用,所以后续*ref_x = 3的操作完全合法,全程不存在两个同时活跃的独立可变引用。
重借用是Rust特意设计的合法规则,不是编译器的特殊处理:我们日常调用接收&mut self的方法时,本质就是自动做了重借用,比如对一个&mut Vec<T>调用push方法,等价于把&mut *vec传给方法参数,如果没有重借用规则,调用一次方法后原可变引用就会失效,完全不符合正常使用需求。
修改后代码不合法的原因
当你把第三行改为let refref_x = &mut x;时,两个可变引用ref_x和refref_x都是直接从x借出的平级独立引用,两个引用的生命周期都覆盖到了后续的赋值操作,同时处于活跃状态,直接违反了「同一值同一时间只能有一个活跃可变引用」的核心约束,所以编译器会直接报错。
内容的提问来源于stack exchange,提问作者s1gsegv
相关产品推荐
相关产品推荐

