使用 None 在 Rust 中访问嵌套的 HashMap
Accessing a nested HashMap in Rust with None
我想创建一个类似于 中的数据结构。因此,一棵 Database
个节点的树,其中包含与该节点关联的一些数据,以及更深的节点。
不同的是,我想允许children
是None
的可能性,表示该节点是叶子。
所以它应该看起来像:
{
"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_mut
将 Option<T>
变成 Option<&mut T>
,从而防止在 unwrap()
node.children
时移出 node
。 =19=]
我想创建一个类似于 Database
个节点的树,其中包含与该节点关联的一些数据,以及更深的节点。
不同的是,我想允许children
是None
的可能性,表示该节点是叶子。
所以它应该看起来像:
{
"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
的新结构实现原始 post 的功能?这可能吗?
注意:我也把原来的砍掉了,这样和上面的代码更相似,也更容易比较。请参阅 here 游乐场 link。
如果您在 children
之后添加 as_mut()
,您的示例将编译,即:
node = node
.children
.as_mut()
.unwrap()
.entry(subkey.to_string())
.or_insert_with(Database::default);
Option::as_mut
将 Option<T>
变成 Option<&mut T>
,从而防止在 unwrap()
node.children
时移出 node
。 =19=]