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

为何在闭包中使用可变引用时未发生重借用?

Rust闭包与可变引用的借用冲突解析

先看这段可以正常编译的代码:

fn bar<T>(v: &mut Vec<T>) {
    bar(v); // 重借用
    bar(v); // 重借用
}

这段代码能通过编译,因为每次调用bar(v)都是临时的重借用,调用结束后借用就归还了,全程不会同时存在多个活跃的可变引用。

但修改为闭包版本后,会触发编译错误:

fn foo<T>(v: &mut Vec<T>) {
    let mut f = ||{
        foo(v);
    };
    let mut g = ||{
        foo(v);
    };
    f();
    g();
}

对应的错误信息如下:

error[E0524]: two closures require unique access to `*v` at the same time
 --> src/lib.rs:5:17
  |
2 |     let mut f = ||{
  |                 -- first closure is constructed here
3 |         foo(v);
  |             - first borrow occurs due to use of `*v` in closure
4 |     };
5 |     let mut g = ||{
  |                 ^^ second closure is constructed here
6 |         foo(v);
  |             - second borrow occurs due to use of `*v` in closure
7 |     };
8 |     f();
  |     - first borrow later used here

核心差异解析

第一个例子中,两次bar(v)是顺序执行的:第一次调用时,v被重借用给bar,函数执行完毕后借用立即归还;第二次调用再重新获取借用,全程没有同时存在两个可变引用的情况。

闭包的情况则完全不同:当创建闭包f和g时,两个闭包都会捕获对v的可变借用权限——由于闭包的执行时机不确定,编译器必须保证在闭包存在的整个周期内,v不能被其他任何地方借用。这里f和g从创建到各自调用完成的阶段是重叠的,相当于同时持有了对*v的可变借用请求,直接违反了Rust的"可变引用唯一"规则,因此编译报错。

哪怕你先调用f()再调用g()也无法解决:编译器在创建g的时候,f还未被销毁(直到函数结束才会释放),此时f仍然持有对v的借用权,g无法再获取新的借用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:37:17