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

为何允许将Rust可变引用转为不可变引用且不违反借用规则?

Rust引用规则的疑问

来自Rust官方书籍:

在任意给定时间,你只能拥有一个可变引用,或任意数量的不可变引用。

考虑以下代码:

fn main() {
    let mut a = 41;
    let b = &mut a;
    let c: &i32 = &a; // [1]
    let d: &i32 = &b;

    println!("{} {}", b, c); // [2]
    println!("{} {}", b, d);
}

尝试编译时会得到如下错误:

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src\main.rs:43:19
   |
42 |     let b = &mut a;
   |             ------ mutable borrow occurs here
43 |     let c: &i32 = &a; // [1]
   |                   ^^ immutable borrow occurs here
44 |     let d: &i32 = &b;
   |                   -- mutable borrow later used here

这符合“只能拥有一个可变引用”的规则。但如果注释掉标记为[1]和[2]的行,代码就能正常编译。此时b是可变引用,d是不可变引用(看似与c情况相同)。

请问为何允许这种场景存在?为何该情况编译通过却不违反“同一时间只能有一个可变引用或多个不可变引用”的规则?


这本质是直接引用原变量和引用“引用”本身的区别,核心看Rust借用检查器追踪的是对原变量a的借用关系:

  • 写let c = &a时,是直接对原变量a创建新的不可变引用,此时a已经被b以可变方式借用,直接触发“可变/不可变引用不能共存”的规则,所以报错。
  • 而let d = &b的情况,你并没有直接借用a,而是借用了可变引用b这个变量本身:
    • d的实际类型是&&mut i32,自动解引用后表现为&i32,但它本质是指向b的不可变引用,不是指向a的。
    • 对原变量a来说,始终只有b这一个可变引用;d只是“挂靠”在b上,没有触碰a的直接借用权限,完全不违反引用规则。

简单说:c是直接抢着借a,和b的借用冲突;d是借b这个“中间人”,没碰a的借用权限,所以合法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:32:19