How can a nested loop with mutations on a HashMap be achieved in Rust?

半腔热情 提交于 2019-12-10 17:32:06

问题


I have the following (trimmed down) Rust code:

use std::collections::HashMap;

struct Node {
    weight:   f64,
    outbound: f64,
}

struct Graph {
    edges: HashMap<u32, HashMap<u32, f64>>,
    nodes: HashMap<u32, Node>,
}

impl Graph {
    fn mutate(&mut self) {
        for (key, value) in self.nodes.iter() {
            if self.edges.contains_key(key) {
                for (target, weight) in self.edges[key].iter() {
                    self.nodes.entry(*target).or_insert(Node::new()).weight;
                }
            }
        }
    }
}

However, I cannot get the code to compile due to Rust ownership rules (playground):

graph.rs:88:25: 88:35 error: cannot borrow `self.nodes` as mutable because it is also borrowed as immutable [E0502]
graph.rs:88                         self.nodes.entry(*target).or_insert(Node::new()).weight;
                                    ^~~~~~~~~~

If I change the first loop to use HashMap::iter_mut() instead, I get a different error (playground):

graph.rs:88:25: 88:35 error: cannot borrow `self.nodes` as mutable more than once at a time [E0499]
graph.rs:88                         self.nodes.entry(*target).or_insert(Node::new()).weight;
                                    ^~~~~~~~~~

How can this kind of nested loop with mutations be achieved in Rust?


回答1:


You can't insert or delete elements in a data structure while you are iterating over it.

As far as I know Rust iterators don't support modification either (like Java iterators' remove()).

So you are left with these options:

  • If there are only a few modifications, you can collect them and execute them after the iteration is finished.

  • If most of the data structure is modified, or if it is small enough that the overhead of copying doesn't matter, you can create a new, modified data structure that replaces the original one after the iteration. This is usually the idiomatic solution, using higher-order functions on iterators like map, flat_map or filter.



来源:https://stackoverflow.com/questions/36281585/how-can-a-nested-loop-with-mutations-on-a-hashmap-be-achieved-in-rust

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!