dynamic - Rust - 使用子节点的输出更新树节点
问题描述
我正在尝试实现一个树结构,其中每个节点都使用其子节点的一些输出进行更新。
在最终应用程序中不能克隆或移动输出。当我为其子节点提供节点引用来更新它时,我遇到了多个借用错误。
我正在使用indextree板条箱。
无法理解它......无法通过这种更新行为找到类似的东西。
我的示例代码:
树包含这样的动态节点
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);
}
推荐阅读
- python - 就 n 和 m 而言,以下算法的运行时复杂度是多少?
- vb.net - 从下拉框中选择项目时尝试激活特定的控制器功能
- php - httpful:当 JSON 属性值是 XML 中的字符串时,响应损坏
- exception - Keycloak 12.0.4 导出抛出异常
- html - 如何为不同的按钮组选择和更改颜色按钮?
- python - Python套接字如何添加多个客户端并向每个客户端发送字节
- javascript - ngx-dataTable 如何应用格式化功能
- node.js - 混淆 node_modules 被 .dockerignore 忽略
- python - arduino pyfirmata 模拟阅读
- php - 以编程方式设置发货 WooCommerce