在 Rust 中使用 None 访问嵌套的 HashMap

Accessing a nested HashMap in Rust with None

提问人:doliphin 提问时间:4/25/2021 更新时间:4/25/2021 访问量:489

问:

我想创建一个类似于这篇文章中的数据结构。因此,包含与该节点关联的一些数据的节点树,以及更深的节点。Database

不同的是,我想允许 是 的可能性,以指示节点是叶子。childrenNone

所以它应该看起来像:

{
  "1": Database {
    {
      data: "element 1",
      children: Some({
        "a": Database {
          data: "element 1-a",
          children: None
        },
        "b": Database {
          data: "element 1-b",
          children: None
        }
      })
    }
  },
  "2": Database {
    {
      data: "element 2",
      children: None
    }
  }
}

使用原始帖子中的代码,我想出了这个 [playground 链接]:

#[derive(Default, Debug)]
struct Database {
    children: Option<HashMap<String, Database>>,
    data: String,
}

impl Database {
    fn insert_path(&mut self, path: &[&str]) -> &mut Self {
        let mut node = self;
        for &subkey in path.iter() {
            if let None = node.children {
                node.children = Some(HashMap::new());
            }
            node = node
                .children
                .unwrap()
                .entry(subkey.to_string())
                .or_insert_with(Database::default);
        }
        node
    }
}

fn main() {
    let mut db = Database {
        children: Some(HashMap::new()),
        data: "root".to_string(),
    };

    let node = db.insert_path(&vec!["key1", "key1.1", "key1.1.3"]);
    node.data = "myvalue".to_string();

    println!("{:#?}", db);
}

这是行不通的。我收到以下错误:

error[E0507]: cannot move out of `node.children` which is behind a mutable reference
  --> src/main.rs:18:20
   |
18 |               node = node
   |  ____________________^
19 | |                 .children
   | |_________________________^ move occurs because `node.children` has type `Option<HashMap<String, Database>>`, which does not implement the `Copy` trait
   |
help: consider borrowing the `Option`'s content
   |
18 |             node = node
19 |                 .children.as_ref()
   |

error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:24:9
   |
18 |               node = node
   |  ____________________-
19 | |                 .children
20 | |                 .unwrap()
   | |_________________________- temporary value created here
...
24 |           node
   |           ^^^^ returns a value referencing data owned by the current function

我对为什么会发生这种情况感到非常困惑。我认为使用 on 会删除移动的值。但是,如果不使用 .我怎样才能通过这个使用的新结构实现原始帖子中的功能?这甚至可能吗?unwrap()node.childrennode.childrenunwrap()None

注意:我还删掉了原来的代码,这样它更像上面的代码,更容易比较。请参阅此处以获取 Playground 链接。

Rust Hashmap 所有权

评论


答:

4赞 sebpuetz 4/25/2021 #1

如果添加一个 after ,则您的示例将编译,即:as_mut()children

node = node
    .children
    .as_mut()
    .unwrap()
    .entry(subkey.to_string())
    .or_insert_with(Database::default);

Option::as_mut将 an 变成 ,从而防止 你 时 的 移出 。Option<T>Option<&mut T>nodeunwrap()node.children