如何在不移动或不需要复制的情况下在闭包中使用 FnMut 参数?
How to use a FnMut argument in a closure without moving it or requiring Copy?
我仍然对 Fn
-FnMut
-FnOnce
与其他特征的关系感到困惑。我想从以下遍历树结构的函数中消除 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
函数更改为引用,这样您就可以像这样传递它
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));
}
我仍然对 Fn
-FnMut
-FnOnce
与其他特征的关系感到困惑。我想从以下遍历树结构的函数中消除 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
函数更改为引用,这样您就可以像这样传递它
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));
}