【发布时间】:2019-05-21 21:12:35
【问题描述】:
我正在尝试在 Rust 中实现 Karger 算法,但在尝试在 while 循环中更新可变哈希映射时遇到了问题。
地图更新成功,但是在下一次克隆时,更新的值似乎没有改变。但是,从地图中删除元素会反映在以后的迭代中。
我已尝试调试和打印地图的值,但事件顺序对我来说没有意义。
use itertools::Itertools; // 0.8.0
use rand::seq::{IteratorRandom, SliceRandom}; // 0.6.5
use std::collections::HashMap;
fn contract_edge(graph: &mut HashMap<i32, Vec<i32>>, num_trials: i32) {
let mut count = 0;
while graph.len() > 2 && count < num_trials {
// clone graph so I can mutate graph later
let imut_graph = graph.clone();
// choose random node
let from_value = imut_graph
.keys()
.choose(&mut rand::thread_rng())
.unwrap()
.clone();
let values = imut_graph.get(&from_value);
let to_value = values
.unwrap()
.choose(&mut rand::thread_rng())
.unwrap()
.clone();
let from_edges = imut_graph[&from_value].iter().clone();
// accessing to_value in imut_graph gives error here later
let to_edges = imut_graph[&to_value]
.iter()
.clone()
.filter(|&x| *x != from_value && *x != to_value);
let new_edges = from_edges.chain(to_edges);
// since I am mutating the graph I thought the next time is is clone it would be updated?
graph.insert(from_value, new_edges.map(|v| v.clone()).collect());
graph.remove(&to_value);
for (_key, val) in graph.iter_mut() {
*val = val
.iter()
.map(|v| if v == &to_value { &from_value } else { v })
.unique()
.cloned()
.collect();
}
count += 1;
}
}
当我尝试访问地图时,我得到 element not found 错误,但已删除的键此时不应存在于向量值中。
我确信这是我对 Rust 中的 (Im)mutability 不了解的地方。
【问题讨论】:
-
您认为
clone方法有什么作用?为什么你认为需要“克隆图,以便我以后可以改变图”? -
回答您的问题有点困难,因为它不包含minimal reproducible example。您的代码可以编译,但不包含演示问题的代码,例如示例 main。如果您尝试在 Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易提供帮助,否则在全新的 Cargo 项目中,然后在 edit 您的问题中包含附加信息。您可以使用Rust-specific MCVE tips 来减少您在此处发布的原始代码。谢谢!
-
@Shepmaster 感谢您的关注,我认为克隆正在制作地图的不可变副本?这是必需的,因为当我尝试访问地图内容然后对其进行变异时,会出现错误。据我了解,我应该克隆现在变异的地图,所以克隆中的值应该更新?
-
@ThomasC 您有机会查看提供的答案吗?怎么不满足你的要求?
标签: rust immutability borrow-checker