You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

&mut T实现Borrow<T>是否违反Rust可变引用规则?

Rust引用规则与Borrow的疑问解答

首先明确Rust引用系统的精确规则:

  • 同一时间,对同一个值,要么只能存在一个可变引用,要么可以存在任意多个不可变引用,二者不可兼得。
  • 所有引用必须始终有效,不能出现悬垂引用(引用指向的内存已被释放)。

接下来分析你提到的两种情况:

情况1:调用r1.borrow()可正常编译

use std::borrow::Borrow;
let mut n = 1;
let r1: &mut i32 = &mut n;
let r2: &i32 = r1.borrow();

println!("log: {r1} {r2}");

这里的核心是:r2是从可变引用r1派生出来的不可变引用,而非直接从原始变量n获取。

Rust的借用检查器能识别这种派生关系:

  • 调用borrow()时,首先会对r1本身进行一次不可变借用(即获取&r1),然后通过解引用得到&T。
  • 在r2的生命周期内,r1会被冻结——你无法再通过r1对n进行可变操作(比如尝试*r1 = 2会直接编译报错)。

这种情况下,并没有打破引用规则:我们并没有同时持有独立的可变引用和不可变引用,而是持有一个被暂时冻结的可变引用,以及从它派生的不可变引用,二者的生命周期严格绑定,不会出现数据竞争的风险。

&mut T实现Borrow<T>的简化逻辑大概是这样的:

impl<T> Borrow<T> for &mut T {
    fn borrow(&self) -> &T {
        &**self // 先解引用得到T的可变引用,再取不可变引用
    }
}

情况2:直接&n会编译报错

修改后的代码:

let mut n = 1;
let r1: &mut i32 = &mut n;
let r2: &i32 = &n; // 编译报错

此时r2是直接从原始变量n获取的不可变引用,和r1是两个独立的引用,都直接指向n。这就违反了Rust的引用规则:同一时间对n同时存在一个可变引用和一个不可变引用,无法保证不会出现数据竞争,因此借用检查器直接阻止这种行为。

内容的提问来源于stack exchange,提问作者Hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:00:15