In the following MWE I have a struct A
that contains a vector of AElem
. Each AElem
contains a map that references other AElem
s.
use std::collections::HashMap;
struct AElem<'b> {
val: HashMap<String, &'b AElem<'b>>,
}
pub struct A<'b> {
data: Vec<AElem<'b>>,
}
impl<'b> A<'b> {
pub fn init() -> A<'b> {
let mut data: Vec<AElem<'b>> = Vec::new();
for _ in 0..10 {
data.push(AElem { val: HashMap::new() });
}
for i in 0..data.len() {
let (left, right) = data.split_at_mut(i);
for j in i - 1..=0 {
right[0].val.insert(format!("{}-{}", i, j), &left[j]);
}
}
println!("{}", data.len());
A { data }
}
}
fn main() {
A::init();
}
The main challenge lies within the storing of references to other AElem
s in the map. For that I need two references to data
; A mutable for manipulating val
, and an immutable which I use as a reference for the map. That I achieve using split_at_mut
. However, I get three compilation errors, that do not really make sense to me (in the context of this code).
error[E0499]: cannot borrow `data` as mutable more than once at a time
--> src/main.rs:20:33
|
11 | impl<'b> A<'b> {
| -- lifetime `'b` defined here
12 | pub fn init() -> A<'b> {
13 | let mut data: Vec<AElem<'b>> = Vec::new();
| -------------- type annotation requires that `data` is borrowed for `'b`
...
20 | let (left, right) = data.split_at_mut(i);
| ^^^^^^^^^^^^^^^^^^^^ `data` was mutably borrowed here in the previous iteration of the loop
I absolutely get that there cannot be multiple mutable references at the same time. However, I do not understand why there are multiple in my code. Is is because I store &left[j]
in the map? If so, what is the proper way to store &data[j]
?
error[E0502]: cannot borrow `data` as immutable because it is also borrowed as mutable
--> src/main.rs:26:24
|
11 | impl<'b> A<'b> {
| -- lifetime `'b` defined here
12 | pub fn init() -> A<'b> {
13 | let mut data: Vec<AElem<'b>> = Vec::new();
| -------------- type annotation requires that `data` is borrowed for `'b`
...
20 | let (left, right) = data.split_at_mut(i);
| -------------------- mutable borrow occurs here
...
26 | println!("{}", data.len());
| ^^^^^^^^^^ immutable borrow occurs here
Why are there still mutable references to data
at this point?
error[E0505]: cannot move out of `data` because it is borrowed
--> src/main.rs:28:13
|
11 | impl<'b> A<'b> {
| -- lifetime `'b` defined here
12 | pub fn init() -> A<'b> {
13 | let mut data: Vec<AElem<'b>> = Vec::new();
| -------- -------------- type annotation requires that `data` is borrowed for `'b`
| |
| binding `data` declared here
...
20 | let (left, right) = data.split_at_mut(i);
| -------------------- borrow of `data` occurs here
...
28 | A { data }
| ^^^^ move out of `data` occurs here
This error I do not get at all. Is there possibly something wrong with the lifetime specifiers?