【发布时间】:2020-06-15 13:05:57
【问题描述】:
我正在尝试实现树 DFS 的修改版本没有递归,并且正在努力使用借用检查器。我的要求是我要确保子节点在其父节点之前被处理,并且我希望所有这些都是可变的(在不可变的情况下没有问题)。
我有一个简单的树结构如下:
struct Node {
value: usize,
children: Vec<Node>,
}
一个普通的迭代 DFS 可能看起来像这样(注意我们正在改变树):
fn normal_dfs(node: &mut Node) {
let mut node_stack = vec![node];
while !node_stack.is_empty() {
let current_node = node_stack.pop().unwrap();
for child_node in &mut current_node.children {
node_stack.push(child_node);
}
current_node.value += 1;
}
}
在上面的函数中,父节点将在其子节点之前被处理,我希望相反。我尝试构建一个对所有树节点的引用堆栈,然后我计划向后迭代,确保子节点在其父节点之前被处理:
fn modified_dfs(node: &mut Node) {
//requirement: child nodes should be treated before parent nodes
let mut node_stack = vec![node];
let mut stack_index = 0usize;
let mut stack_size = node_stack.len(); //not great but helps with borrow checker
while stack_index < stack_size {
let current_node = node_stack.get_mut(stack_index).unwrap();
for child_node in &mut current_node.children {
node_stack.push(child_node);
}
stack_size = node_stack.len();
stack_index += 1;
}
//iterate stack in reverse to make sure child nodes are treated before parents
for current_node in node_stack.iter_mut().rev() {
current_node.value += 1;
}
}
编译时出错:
error[E0499]: cannot borrow `node_stack` as mutable more than once at a time
--> src/lib.rs:13:28
|
13 | let current_node = node_stack.get_mut(stack_index).unwrap();
| ^^^^^^^^^^ `node_stack` was mutably borrowed here in the previous iteration of the loop
error[E0499]: cannot borrow `node_stack` as mutable more than once at a time
--> src/lib.rs:15:13
|
13 | let current_node = node_stack.get_mut(stack_index).unwrap();
| ---------- first mutable borrow occurs here
14 | for child_node in &mut current_node.children {
| -------------------------- first borrow later used here
15 | node_stack.push(child_node);
| ^^^^^^^^^^ second mutable borrow occurs here
error[E0502]: cannot borrow `node_stack` as immutable because it is also borrowed as mutable
--> src/lib.rs:18:22
|
13 | let current_node = node_stack.get_mut(stack_index).unwrap();
| ---------- mutable borrow occurs here
...
18 | stack_size = node_stack.len();
| ^^^^^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
error[E0499]: cannot borrow `node_stack` as mutable more than once at a time
--> src/lib.rs:23:25
|
13 | let current_node = node_stack.get_mut(stack_index).unwrap();
| ---------- first mutable borrow occurs here
...
23 | for current_node in node_stack.iter_mut().rev() {
| ^^^^^^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
我想我理解错误的原因:我在迭代中借用了node_stack,并且在迭代结束时借用没有“释放”,因为子节点已被放入堆栈(它编译如果你不推送子节点)。
执行此操作的迭代算法是什么?
【问题讨论】:
-
这很可能是 Safe Rust 过于有限的情况之一。您可能不得不求助于
unsafe,或者,如果您不想这样做,请使用RefCells 将检查 Rust 的借用规则推迟到运行时。
标签: rust tree depth-first-search