0

I have the following Rust structure which has a HashMap to children structures.

use std::collections::HashMap; #[derive(Debug)] struct Node { children: HashMap<i32, Node>, } impl Node { fn no_children(&self) -> usize { if self.children.is_empty() { 1 } else { 1 + self .children .into_iter() .map(|(_, child)| child.no_children()) .sum::<usize>() } } } 

I implemented no_children(&self) to find the total number of nodes. However, under self.children, Rust highlights an error because:

error[E0507]: cannot move out of `self.children` which is behind a shared reference --> src/lib.rs:13:17 | 13 | 1 + self | _________________^ 14 | | .children | |_________________________^ move occurs because `self.children` has type `std::collections::HashMap<i32, Node>`, which does not implement the `Copy` trait 

I am not sure what is missing. I have tried adding &self.children... but still got the same error.

2
  • 1
    As a side note, your no_immediate_children counts all the children recursively, not just the immediate ones… Commented Oct 16, 2019 at 6:17
  • @Jmb thanks, I have edited that in my code. Commented Oct 16, 2019 at 14:37

1 Answer 1

2

The issue is that .into_iter(self) needs to take ownership of the HashMap, but in no_immediate_children(&self) the HashMap is behind a reference -> i.e. &self instead of self;

You can work around that in two ways, depending on what you want to achieve:

  1. If you want to consume the elements of the hash map and leave it empty after the method invocation:

    • Change the receiver to &mut self
    • Use .drain() instead of .into_iter():

      self.children.drain().map(|(_, mut v)| v.no_immediate_children()).sum::<usize>() + 1 
  2. If you just want to get the sum, but do not want to modify the HashMap:

    • Use .iter() instead of .into_iter():

      self.children.iter().map(|(_k, v)| v.no_immediate_children()).sum::<usize>() + 1 
  3. You want to consume the whole Node chain:

    • Change the method signature to fn no_immediate_children(self) and use .into_iter() as it is.
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.