【发布时间】:2019-02-02 09:20:45
【问题描述】:
我有一个需要递归传递闭包参数的函数
use std::cell::RefCell;
use std::rc::Rc;
pub struct TreeNode {
val: i32,
left: Option<Rc<RefCell<TreeNode>>>,
right: Option<Rc<RefCell<TreeNode>>>,
}
pub fn pre_order<F>(root: Option<Rc<RefCell<TreeNode>>>, f: F)
where
F: FnOnce(i32) -> (),
{
helper(&root, f);
fn helper<F>(root: &Option<Rc<RefCell<TreeNode>>>, f: F)
where
F: FnOnce(i32),
{
match root {
Some(node) => {
f(node.borrow().val);
helper(&node.borrow().left, f);
helper(&node.borrow().right, f);
}
None => return,
}
}
}
这不起作用:
error[E0382]: use of moved value: `f`
--> src/lib.rs:23:45
|
22 | f(node.borrow().val);
| - value moved here
23 | helper(&node.borrow().left, f);
| ^ value used here after move
|
= note: move occurs because `f` has type `F`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `f`
--> src/lib.rs:24:46
|
23 | helper(&node.borrow().left, f);
| - value moved here
24 | helper(&node.borrow().right, f);
| ^ value used here after move
|
= note: move occurs because `f` has type `F`, which does not implement the `Copy` trait
如果我尝试将 f 的类型从 f: F 更改为 f: &F,我会收到编译器错误
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:22:17
|
22 | f(node.borrow().val);
| ^ cannot move out of borrowed content
我该如何解决这个问题?
我这样调用函数:
let mut node = TreeNode::new(15);
node.left = Some(Rc::new(RefCell::new(TreeNode::new(9))));
let node_option = Some(Rc::new(RefCell::new(node)));
pre_order(node_option, |x| {
println!("{:?}", x);
});
【问题讨论】:
-
F是否需要为FnOnce()类型?如果将其更改为输入Fn()并使helper()接受&F,它将起作用。F:FnOnce()使闭包F按值移动到调用中,因此只能使用一次。