trait OnUpdate {
fn on_update(&mut self, x: &i32);
}
struct Foo {
field: i32,
cbs: Vec<Box<OnUpdate>>,
}
struct Bar {
foos: Vec<Foo>,
}
impl Bar {
fn call_foo_cb(&mut self) {
self.foos
.iter_mut()
.for_each(|foo| foo.cbs.iter_mut().for_each(|cb| cb.on_update(&self.value(*foo)))) // compile error see below
// .for_each(|foo| foo.cbs.iter_mut().for_each(|cb| cb.on_update(&10))) // works
}
fn value(&self, foo: Foo) -> i32 {
foo.field + self.foos.len() as i32 // pretend some calculation based on the current foo and self
}
}上面的代码是为了演示我的问题。我是生锈新手,我想知道用惯用的生锈方式改造的最好方法是什么。
提前谢谢。
--> src/lib.rs:348:23
|
346 | self.foos
| --------- mutable borrow occurs here
347 | .iter_mut()
348 | .for_each(|foo| foo.cbs.iter_mut().for_each(|cb| cb.on_update(&self.value(*foo))))
| -------- ^^^^^ immutable borrow occurs here ---- second borrow occurs due to use of `self` in closure
| |
| mutable borrow later used by call发布于 2021-02-01 05:57:36
对于我来说,使用for循环更容易解释这一点,因此请考虑以下等价的内容:
for foo in &mut self.foos {
for cb in &mut foo.cbs {
cb.on_update(&self.value(foo));
}
}如果计算值不依赖于cb,则可以将其移出循环:
for foo in &mut self.foos {
let x = self.value(foo);
for cb in &mut foo.cbs {
cb.on_update(&x);
}
}然后,您可以将可变循环更改为一个使用索引的循环,以避免创建可变的借入,直到以后:
for i in 0..self.foos.len() {
let x = self.value(&self.foos[i]);
for cb in &mut self.foos[i].cbs {
cb.on_update(&x);
}
}这段代码假定value函数实际上引用了Foo,因为它不是Copy或Clone。
https://stackoverflow.com/questions/65987363
复制相似问题