使用None访问Rust中的嵌套HashMap



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

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

#[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的新结构,我如何能够实现原帖子中的功能?这可能吗?

注意:我还对原始代码进行了删减,这样它与上面的代码更相似,也更容易进行比较。请参阅此处获取游乐场链接。

如果在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

最新更新