我基本上有以下代码需要修改向量场(通过函数删除一些项目retains
),并且在该函数的谓词中retains
,我需要在 self 上调用一个可变函数:
struct Task {}
struct Processor {
counter: u32,
tasks: Vec<Task>
}
impl Processor {
fn execute(&mut self, task: &Task) -> bool {
self.counter += 1;
// Do some stuff with task and return wether it was sucessfully executed
true
}
fn run(&mut self) {
self.tasks.retain(|task| !self.execute(task))
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨两个错误:
error[E0501]: cannot borrow `self.tasks` as mutable because previous closure requires unique access
--> src/main.rs:90:9
|
90 | self.tasks.retain(|task| !self.execute(task))
| ^^^^^^^^^^^------^------^^----^^^^^^^^^^^^^^^
| | | | |
| | | | first borrow occurs due to use of `self` in closure
| | | closure construction occurs here
| | first borrow later used by call
| second borrow occurs here
error[E0500]: closure requires unique access to `self` but it is already borrowed
--> src/main.rs:90:27
|
90 | self.tasks.retain(|task| !self.execute(task))
| ---------- ------ ^^^^^^ ---- second borrow occurs due to use of `self` in closure
| | | |
| | | closure construction occurs here
| | first borrow later used by call
| borrow occurs here
Run Code Online (Sandbox Code Playgroud)
我确实理解这个问题,但我该如何使其发挥作用?
Rust 还没有办法只借用self
. 因此,它不能推断您没有self.tasks
同时发生突变self.counter
。它只知道你试图self
同时突变两次。
要解决此问题,您需要移出tasks
,self
然后执行所需的操作,然后将其移回self
。
Rust 有一个方便的操作,可以在标准库中完成此操作。由于Vec
实现了Default
(产生一个空向量,不需要分配),我们可以使用std::mem::take
:
fn run(&mut self) {
// swaps `self.tasks` with an empty `Vec`, and yields `tasks` to us
// this won't allocate, because `Vec::new` and therefore `Vec::default` do not
let mut tasks = std::mem::take(&mut self.tasks);
// do what we want with it
tasks.retain(|task| !self.execute(task));
// move it back into `self`
self.tasks = tasks;
}
Run Code Online (Sandbox Code Playgroud)