[rust-dev] Flatten a tree into HashMap, how do I pass a &mut around?

Vladimir Pouzanov farcaller at gmail.com
Sun Jun 15 02:50:22 PDT 2014


After a few hints on IRC I managed to simplify it to:

fn collect_node_names(&self, map: &mut HashMap<String, Gc<node::Node>>,
    nodes: &Vec<Gc<node::Node>>) -> bool {
  for n in nodes.iter() {
    if !self.collect_node_names(map, &n.subnodes) {
      return false;
    }

    match n.name {
      Some(ref name) => {
        if map.contains_key(name) {
          self.sess.span_diagnostic.span_err(n.name_span, format!(
              "duplicate `{}` definition", name).as_slice());

          self.sess.span_diagnostic.span_warn(
              map.get(name).name_span,
              "previously defined here");
          return false;
        } else {
          map.insert(name.clone(), *n);
        }
      },
      None => (),
    }
  }
  true
}

My failure point was that I didn't realise you cannot access &mut while yo
have a reference to anything you pass &mut to.


On Sun, Jun 15, 2014 at 8:14 AM, Vladimir Pouzanov <farcaller at gmail.com>
wrote:

> I have a tree of Nodes where each node might have a name. I'm trying to
> convert the tree into a HashMap of named nodes, but my code is getting
> extremely complex due to the fact that I cannot pass &mut HashMap around.
>
> let mut named_nodes = HashMap::new();
> let nodes = vec!( ... );
> named_nodes = self.collect_node_names(&named_nodes, &nodes);
> println!('{}', named_nodes);
>
> fn collect_node_names(&self, map: &HashMap<String, Gc<node::Node>>,
>     nodes: &Vec<Gc<node::Node>>) -> HashMap<String, Gc<node::Node>> {
>   let mut local_map: HashMap<String, Gc<node::Node>> = HashMap::new();
>   for (k,v) in map.iter() {
>     local_map.insert(k.clone(), *v);
>   }
>   for n in nodes.iter() {
>     for (k,v) in self.collect_node_names(&local_map, &n.subnodes).iter() {
>       local_map.insert(k.clone(), *v);
>     }
>     match n.name {
>       Some(ref name) => {
>         if local_map.contains_key(name) {
>
>         } else {
>           local_map.insert(name.clone(), *n);
>         }
>       },
>       None => (),
>      }
>   }
>   local_map
> }
>
> this one works, but it's bloated and slow. Any hints on how to improve the
> code?
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140615/354f7c3a/attachment.html>


More information about the Rust-dev mailing list