【发布时间】:2017-12-10 08:20:18
【问题描述】:
我今年尝试在 Rust 中出现代码,作为学习语言的一种方式。我已将输入(从第 7 天开始)解析为以下结构:
struct Process {
name: String,
weight: u32,
children: Vec<String>,
parent: Option<String>
}
这些存储在HashMap<String, Process> 中。现在,我想根据我在父级的“子级”向量中找到的内容迭代地图中的值并更新父级值。
没用的是
for p in self.processes.values() {
for child_name in p.children {
let mut child = self.processes.get_mut(child_name).expect("Child not found.");
child.parent = p.name;
}
}
我不能同时拥有对HashMap (self.processes) 的可变引用和非可变引用,或者两个可变引用。
那么,在 Rust 中实现这一点最惯用的方法是什么?我可以看到的两个选项是:
- 在不可变引用超出范围后,一次性将父/子关系复制到新的临时数据结构中,然后在第二遍中更新 Process 结构。
- 更改我的数据结构,将“父级”放入它自己的 HashMap 中。
还有第三种选择吗?
【问题讨论】:
-
在我看来很明显
self.processes是HashMap<String, Process>。 -
我可能会选择
Vec<Process>,并使用usize作为其他条目的参考。可以使用两遍方法:首先构建HashMap<String, usize>并填充name+weight,在第二遍中填充children和parent。很多可能性:) -
@Stefan:嗯,我只是不喜欢使用不完整的代码;不过,我想这是一个可以推理的问题。
-
另一种选择是将
parent的类型更改为RefCell<Option<String>>- 即使您只有一个 const 引用,这也将允许更改父级。 -
另请注意,您需要克隆字符串以将其从
p.name复制到child.parent- 您不能将其移出借用的上下文(即使可以)。
标签: rust borrow-checker