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

如何在多个Rust闭包中使用可变借用?

如何在多个Rust闭包中共享并修改外部可变变量?

你尝试用两个闭包修改同一个外部可变变量的代码如下:

let mut i: i32 = 0;

let mut add = || {
    i += 1;
};
let mut sub = || {
    i -= 1;
};
add();
sub();

这段代码编译失败,报错信息如下:

error[E0499]: cannot borrow i as mutable more than once at a time
--> src/main.rs:14:19
|
11 | let mut add = || {
| -- first mutable borrow occurs here
12 | i += 1;
| - first borrow occurs due to use of i in closure
13 | };
14 | let mut sub = || {
| ^^ second mutable borrow occurs here
15 | i -= 1;
| - second borrow occurs due to use of i in closure
16 | };
17 | add();
| --- first borrow later used here

这是因为Rust的借用规则禁止同一时间对同一个变量存在多个可变借用,而每个闭包都试图获取i的可变借用,导致冲突。以下是几种可行的解决方法:

1. 单线程场景:使用RefCell

RefCell提供内部可变性,允许在持有不可变引用的同时修改内部数据,它通过运行时的借用检查来保证安全(如果违反规则会 panic)。

use std::cell::RefCell;

let i = RefCell::new(0);

let mut add = || {
    *i.borrow_mut() += 1;
};
let mut sub = || {
    *i.borrow_mut() -= 1;
};

add();
sub();
println!("{}", *i.borrow()); // 输出0

2. 针对Copy类型:使用Cell

如果你的变量是Copy类型(比如i32、bool这类可以直接复制的类型),可以用更轻量的Cell,它不需要借用操作,直接通过get和set来读写值:

use std::cell::Cell;

let i = Cell::new(0);

let mut add = || {
    i.set(i.get() + 1);
};
let mut sub = || {
    i.set(i.get() - 1);
};

add();
sub();
println!("{}", i.get()); // 输出0

3. 多线程场景:使用Arc<Mutex>

如果闭包需要在多线程环境中运行,需要结合Arc(原子引用计数,用于多线程共享所有权)和Mutex(互斥锁,保证同一时间只有一个线程能修改数据):

use std::sync::{Arc, Mutex};
use std::thread;

let i = Arc::new(Mutex::new(0));

// 克隆Arc,传递给第一个线程
let i_clone = Arc::clone(&i);
let add_handle = thread::spawn(move || {
    let mut num = i_clone.lock().unwrap();
    *num += 1;
});

// 再次克隆Arc,传递给第二个线程
let i_clone2 = Arc::clone(&i);
let sub_handle = thread::spawn(move || {
    let mut num = i_clone2.lock().unwrap();
    *num -= 1;
});

// 等待线程执行完成
add_handle.join().unwrap();
sub_handle.join().unwrap();

println!("{}", *i.lock().unwrap()); // 输出0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:51:21