I am trying to construct a bunch of linked-list data-structure in Rust, but different than other examples I've seen, I'd like the actual nodes to be owned by a HashMap
. It seems like if a HashMap
owns the nodes, then lifetimes shouldn't be an issue and this should allow me to reference the next element in my list by Option<&List>
rather than Box<List>
(as done in Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time ). However, I am getting mutable/immutable borrow errors.
My minimal example is:
use std::collections::HashMap;
#[derive(Debug, Default)]
struct List<'a> {
data: i32,
child: Option<&'a List<'a>>,
}
fn main() {
let mut map = HashMap::<i32, List>::new();
let data = vec![(1, None), (2, Some(1))];
for (data, child) in data.iter() {
println!("Inserting {:?} with child {:?}", data, child);
let new_node = map.entry(*data).or_insert(List {
data: *data,
child: None,
});
match child {
Some(child_data) => {
map.get(child_data).map(|child_node| {
new_node.child = Some(child_node);
});
}
None => {}
}
}
println!("Data: {:?}", map);
}
Which gives the error
error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
--> src/main.rs:16:24
|
16 | let new_node = map.entry(*data).or_insert(List {
| ^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
22 | map.get(child_data).map(|child_node| {
| --- immutable borrow occurs here
error[E0502]: cannot borrow `map` as immutable because it is also borrowed as mutable
--> src/main.rs:22:17
|
16 | let new_node = map.entry(*data).or_insert(List {
| --- mutable borrow occurs here
...
22 | map.get(child_data).map(|child_node| {
| ^^^ immutable borrow occurs here
23 | new_node.child = Some(child_node);
| -------- mutable borrow later captured here by closure
My question is, is this error a result of me not setting up the List
struct correctly, a result of the way I am using HashMap
, and how can I fix it?
(1, Some(1)
), thennew_node
andmap.get(...)
will alias. – Lambda FairyHashMap
is backed by a growable array. Every time the hashtable fills up, it will reallocate and invalidate all existing references. So what you're doing is fundamentally impossible. – Lambda FairyBox
things and send bothList
andHashMap
the boxed type? – Jason Siefken