You are calling tasks.iter()
which produces immutable references to the elements of Vec
. You actually get back &&mut Task
, an immutable reference to a mutable one (that is why the Rust compiler is complaining).
To solve this, call tasks.iter_mut()
to get an iterator of mutable references.
The second problem is calling defining work_one
as a method. You already borrow a mutable reference from self
when iterating, so you cannot get another borrow.
Working example (playground):
trait Task {
fn do_it(&mut self);
}
struct Worker<'a> {
tasks: Vec<&'a mut Task>,
}
impl<'a> Worker<'a> {
pub fn work(&mut self) {
for task in self.tasks.iter_mut() {
Worker::work_one(*task);
}
}
fn work_one(task: &mut Task) {
task.do_it();
}
}
To still have access to self
in work_one
this workaround can be used. This basically just swaps the two vectors so you do not actually borrow self
when iterating and then swapping it back. This is ugly, there may be a better pattern here, maybe someone else will suggest something better.
pub fn work(&mut self) {
let mut tasks = vec![];
mem::swap(&mut tasks, &mut self.tasks);
for task in tasks.iter_mut() {
self.work_one(*task);
}
mem::swap(&mut tasks, &mut self.tasks);
}
A nicer alternative suggested by @Veedrac:
fn work(&mut self) {
let mut tasks = mem::replace(&mut self.tasks, Vec::new());
for task in &mut tasks {
self.work_one(*task);
}
self.tasks = tasks;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…