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

Accessing a nested HashMap in Rust with None

我想创建一个类似于 中的数据结构。因此,一棵 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
    }
  }
}

使用, I've come up with this [playground link]中的代码:

#[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

我很困惑为什么会这样。我认为在 node.children 上使用 unwrap() 会降低移动的值 node.children。但是,如果不使用 unwrap(),我看不出如何做到这一点。我怎样才能使用这个使用 None 的新结构实现原始 post 的功能?这可能吗?

注意:我也把原来的砍掉了,这样和上面的代码更相似,也更容易比较。请参阅 here 游乐场 link。

如果您在 children 之后添加 as_mut(),您的示例将编译,即:

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

Option::as_mutOption<T> 变成 Option<&mut T>,从而防止在 unwrap() node.children 时移出 node。 =19=]