Rust - 使用子节点的输出更新树节点

Rust - update tree node with output from children

我正在尝试实现一个 结构,其中每个节点都是 更新的 使用其 子节点的一些输出.

无法在最终应用程序中克隆或移动输出。当我给它的子节点的节点引用来更新它时,我 运行 陷入了多次借用错误。

我正在使用 indextree 箱子。

我无法理解它...无法通过这种更新行为找到类似的东西。

我的例子code :

树包含这样的动态节点

type NodeOutput = i64; //(Can't be copied) wgpu::TextureView in final version  

trait CalcNode {
    fn update(&mut self, input: Vec<&dyn CalcNode>);
    fn output(&self) -> NodeOutput;
}
 
struct NodeModel {
    output: NodeOutput, // generated output ()
    internal: i64,      // some internal state
}
 
impl CalcNode for NodeModel {
    //input can't be cloned/copied in final version
    fn update(&mut self, input: Vec<&dyn CalcNode>) {
        //example for a possible update function
        let child_input: i64 = input.iter().map(|&f| f.output()).sum();
        self.output = self.internal * child_input;
        self.internal += 1 
        // this is only an simplified example 
        //the final version is rendering to a Texture
    }
 
    fn output(&self) -> NodeOutput {
        // output is not copy-able in final version
        self.output
    }
}
 
impl NodeModel {
    fn new(internal: i64) -> Self {
        Self {
            output: internal,
            internal,
        }
    }
}

然后我尝试像这样更新树:

use indextree::{Arena, NodeId};

fn main() {
    let (mut arena_, root) = build_tree(); //generate some Tree
    let arena = &mut arena_;
 

    let node_stack: Vec<NodeId> = root.descendants(arena).collect(); //collect all nodes depth first
 

        //update in reverse order deepest node first, ROOT LAST.
        for &n in node_stack.iter().rev() {

            // collect updated children when available
            let children: Vec<&dyn CalcNode> = {
                n.children(arena)
                    .map(|f| arena.get(f).unwrap().get().as_ref())
                    .collect()
            };
 
            //get the node to update
            //--- can't borrow arena here to get the node ---
            let node = { arena.get_mut(n).unwrap().get_mut().as_mut() }; 
 
            // update the node
            node.update(children);
        }
    
}

CalcNode::update 函数实际上不需要访问它的子函数——实际上它只需要从它们计算的值,所以您可以将计算移出 update 函数以防止别名引用:

fn update(&mut self, child_input: i64) {
    self.output = self.internal * child_input;
    self.internal += 1
}
// <-- Main loop
for &n in node_stack.iter().rev() {
    // collect updated children when available
    let children: Vec<&dyn CalcNode> = {
        n.children(arena)
            .map(|f| arena.get(f).unwrap().get().as_ref())
            .collect()
    };
    //example for n possible update funciton
    let child_input: i64 = children.iter().map(|&f| f.output()).sum();

    //get the node to update
    let node = { arena.get_mut(n).unwrap().get_mut().as_mut() };
    node.update(child_input);
}