代码之家  ›  专栏  ›  技术社区  ›  hydradon

rust hashmap inside struct error:无法移出共享引用后面的xxx

  •  0
  • hydradon  · 技术社区  · 5 年前

    我有下面的rust结构,它有一个到子结构的hashmap。

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

    我执行 no_immediate_children(&self) 以查找节点总数。然而,在 self.children ,rust会突出显示错误,因为:

    cannot move out of `self.children` which is behind a shared reference
    
    move occurs because `self.children` has type `std::collections::HashMap<i32, Node>`, which does not implement the `Copy` trait
    

    我不知道丢失了什么。我刚开始生锈。我试着加上 &self.children... 但还是犯了同样的错误。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Svetlin Zarev    5 年前

    问题是 .into_iter(self) 需要取得hashmap的所有权,但在您的情况下 no_immediate_children(&self) 它在一个引用的后面,即。 &self 而不是 self (二)

    你可以通过两种方式来解决这一问题,具体取决于你想要实现的目标:

    1. 如果要使用哈希映射的元素,并在方法调用后将其保留为空:

      • 将接收器更改为 &mut self
      • 使用 .drain() 而不是 .into_iter() 以下内容:

        self.children.drain().map(|(_, mut v)| v.no_immediate_children()).sum::<usize>() + 1
        
    2. 如果只想得到和,但不想修改哈希映射:

      • 使用 .iter() 而不是 .into_iter() 以下内容:

        self.children.iter().map(|(_k, v)| v.no_immediate_children()).sum::<usize>() + 1
        
    3. 你想把整个 Node 链条:

      • 将方法签名更改为 fn no_immediate_children(self) 使用 .into_iter() 事实上。