Rust中通过可变引用获取内部值可变引用的规则是什么
Rust可变引用规则差异说明
核心底层规则
1. 可变引用排他性
Rust所有权系统强制要求:同一时间,同一块内存区域只能存在一个活跃的可变引用,且可变引用活跃期间,不允许创建其他指向同一块内存的可变/不可变引用。
2. 借用拆分规则
针对结构体、元组、数组这类复合类型,Rust借用检查器支持细粒度的借用拆分:如果你持有一个复合类型的可变引用,可以安全拆分出多个指向其不同字段的可变引用,只要子引用指向的字段没有重叠,就不会和父引用判定为冲突,且子引用的生命周期不能超过父引用。
3. 非词法生命周期(NLL)
引用的生命周期仅持续到它最后一次被使用的位置,而非整个作用域结束,只要引用不再被使用,对应的借用就会自动释放。
两个写法的差异分析
可运行写法的合法性
第一种写法中let inner = &mut outer.inner属于合法的借用拆分:
- 首先
let outer = &mut test拿到了整个test实例的可变借用 - 从
outer拆分出inner字段的可变引用后,inner临时持有outer.inner的使用权,此时outer的其他字段(如name)仍然可以正常使用 - 执行完
*inner = Inner { val: String::from("x") }后,inner不再被使用,其生命周期结束,outer.inner的使用权归还给outer - 后续调用
outer.inner.val.push('b')时,outer的借用是完整有效的,没有冲突,因此可以正常编译。
报错写法的问题原因
第二种写法中let inner = &mut test.inner直接从根变量test创建可变引用,违反了排他性规则:
- 第一步
let outer = &mut test已经对整个test实例做了可变借用,在outer的生命周期结束前,整个test的内存都处于被锁定的状态,不允许再创建任何其他指向test任意部分的借用 - 此时直接从
test创建test.inner的可变引用,相当于同时存在两个冲突的可变引用:一个是覆盖整个test的outer,一个是覆盖test.inner的inner - 后续
outer.inner.val.push('b')还在使用outer,说明outer的借用直到这一行都是活跃状态,两个冲突的可变引用同时存在,因此编译器抛出E0499错误。
内容的提问来源于stack exchange,提问作者user1127820
相关产品推荐
相关产品推荐

