【问题标题】:HashMap inside struct error: cannot move out of xxx which is behind a shared reference [duplicate]结构错误中的HashMap:无法移出共享引用后面的xxx [重复]
【发布时间】:2020-02-12 18:37:37
【问题描述】:

我有以下 Rust 结构,其子结构具有 HashMap

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>()
        }
    }
}

我实现了no_children(&amp;self) 来查找节点总数。但是,在self.children 下,Rust 会突出显示一个错误,因为:

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

我不确定缺少什么。我尝试添加&amp;self.children...,但仍然出现同样的错误。

【问题讨论】:

  • 附带说明,您的no_immediate_children 递归计算所有子项,而不仅仅是直接子项……
  • @Jmb 谢谢,我已经在我的代码中编辑了它。

标签: rust


【解决方案1】:

问题是.into_iter(self) 需要拥有HashMap 的所有权,但在no_immediate_children(&amp;self) 中,HashMap 在引用后面-> 即&amp;self 而不是self

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

  1. 如果你想在方法调用后消费散列映射的元素并留空:

    • 将接收者改为&amp;mut self
    • 使用.drain() 代替.into_iter()

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

    • 使用.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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 2020-11-30
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多