[英]How to use a FnMut argument in a closure without moving it or requiring Copy?
我仍然對Fn
- FnMut
- FnOnce
事情如何與其他特征一起工作感到有些困惑。 我想從以下 function 中消除Copy
約束以遍歷樹結構。
pub fn for_each<F>(&mut self, mut f: F)
where
F: FnMut(&mut Tree<T>) + Copy,
{
self.children.iter_mut().for_each(|c| c.for_each(f));
f(self);
}
這樣做的原因是我試圖傳遞一個將外部變量修改為for_each
的閉包,而Copy
阻止了這種情況( E0277
)。 但是,當我擺脫Copy
時,我收到以下錯誤消息:
error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
--> src/tree.rs:34:58
|
30 | pub fn for_each<F>(&mut self, mut f: F)
| ----- captured outer variable
...
34 | self.children.iter_mut().for_each(|c| c.for_each(f));
| ^ move occurs because `f` has type `F`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `f`
--> src/tree.rs:35:9
|
30 | pub fn for_each<F>(&mut self, mut f: F)
| ----- move occurs because `f` has type `F`, which does not implement the `Copy` trait
...
34 | self.children.iter_mut().for_each(|c| c.for_each(f));
| --- - variable moved due to use in closure
| |
| value moved into closure here
35 | f(self);
| ^ value borrowed here after move
|
help: consider further restricting this bound
|
32 | F: FnMut(&mut Tree<T>) + Copy,
| ^^^^^^
error: aborting due to 2 previous errors
我該如何解決這個問題? 如果這樣更容易,我也願意將它變成一個迭代器。
原因是for_each
擁有f
的所有權。
這意味着,一旦您調用c.for_each(f)
,您就失去了f
的所有權,因此您以后不能使用f
。 為了解決這個問題,您可以更改for_each
function 以代替參考,因此您可以像這樣傳遞它
pub fn for_each<F>(&mut self, f: &mut F)
where
F: FnMut(&mut Tree<T>),
{
// Only a reference is passed into for_each here
self.children.iter_mut().for_each(|c| c.for_each(f));
// f can be used again, as reference is reborrowed implicitly
f(self);
}
或者您也可以(如果可能)將呼叫移至f
上一行,如下所示
pub fn for_each<F>(&mut self, mut f: F)
where
F: FnMut(&mut Tree<T>),
{
// f is used, but ownership is kept
f(self);
// ownership of f can now be transferred, as there is no further use of it
self.children.iter_mut().for_each(|c| c.for_each(f));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.