簡體   English   中英

如何在閉包中使用 FnMut 參數而不移動它或需要復制?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM