【发布时间】:2021-11-08 21:40:16
【问题描述】:
我尝试递归地遍历一棵玫瑰树。以下代码也可以按预期工作,但由于借用检查器的问题,我仍然需要克隆值。因此,如果有办法从克隆变成更好的东西,那就太好了。
如果没有 clone() rust 抱怨(正确地)我通过查看子节点和第二次在闭包中借用 self mutable。
整个结构和代码比下面显示的更复杂和更大,但这是核心元素。我是否必须更改数据结构或者我错过了一些明显的东西?如果数据结构是问题,你会如何改变它?
此外,NType 枚举在这里似乎有点用处,但我还有一些其他类型需要考虑。这里内部节点总是有子节点,而外部节点永远不会。
enum NType{
Inner,
Outer
}
#[derive(Eq, PartialEq, Clone, Debug)]
struct Node {
// isn't a i32 actually. In my real program it's another struct
count: i32,
n_type: NType,
children: Option<Vec<usize>>
}
#[derive(Eq, PartialEq, Clone, Debug)]
struct Tree {
nodes: Vec<Node>,
}
impl Tree{
pub fn calc(&mut self, features: &Vec<i32>) -> i32{
// root is the last node
self.calc_h(self.nodes.len() - 1, features);
self.nodes[self.nodes.len() - 1].count.clone()
}
fn calc_h(&mut self, current: usize, features: &Vec<i32>){
// do some other things to decide where to go into recursion and where not to
// also use the features
if self.nodes[current].n_type == Inner{
//cloneing is very expensiv and destroys the performance
self.nodes[current].children.as_ref().unwrap().clone().iter().for_each(|&n| self.calc_h(n, features));
self.do_smt(current)
}
self.do_smt(current)
}
}
编辑:
- Lagerbaer 建议使用 as_mut 但这会导致 current 成为 &mut 使用大小,这并不能真正解决问题。
- 把孩子变成了孩子
【问题讨论】:
-
你试过
as_mut而不是.as_ref吗? -
这里的问题是它在一行中做的太多了。添加临时变量,一个正常的 for 循环,它更容易弄清楚。 clone() 的额外问题是您对节点的副本进行操作,并且无论您计算什么(我想如果您想改变它们,我想您将结果放入节点中)将在下一行被遗忘。你能完成代码示例吗?节点没有 calc_h,childs 类型似乎错误。
标签: recursion rust mutable borrow-checker