我有一个函数需要递归地传递闭包参数
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,
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用:
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,
}
}
}
Run Code Online (Sandbox Code Playgroud)
f如果我尝试更改from的类型,f: F则会f: &F出现编译器错误
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
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
我这样调用该函数:
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);
});
Run Code Online (Sandbox Code Playgroud)
FnOnce是最普遍的功能约束。但是,这意味着您的代码必须适用于所有可能的功能,包括那些消耗其环境的功能。这就是它被称为的原因:您对它唯一了解的是它至少FnOnce可以被调用一次 - 但不一定会被多次调用。在内部我们只能假设每种可能的情况都是正确的:它只能被调用一次。pre_order F
如果将其更改为Fn或FnMut,以排除消耗其环境的闭包,您将能够多次调用它。FnMut是下一个最通用的函数特征,因此最好接受它而不是Fn,以确保您可以接受最多的函数:
pub fn pre_order<F>(root: Option<Rc<RefCell<TreeNode>>>, mut f: F)
where
F: FnMut(i32),
{
helper(&root, &mut f);
fn helper<F>(root: &Option<Rc<RefCell<TreeNode>>>, f: &mut F)
where
F: FnMut(i32),
{
match root {
Some(node) => {
f(node.borrow().val);
helper(&node.borrow().left, f);
helper(&node.borrow().right, f);
}
None => return,
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |