Rust Lifetime is really a puzzle to me, and here is the problem
#[derive(Debug)]
pub struct Container<'a> {
contains: Vec<&'a str>,
}
#[derive(Debug)]
pub struct Space<'a> {
elems: Vec<String>,
packages: Vec<Container<'a>>,
}
impl<'a> Space<'a> {
pub fn new() -> Space<'a> {
Space {
elems: Vec::new(),
packages: Vec::new(),
}
}
pub fn increase(&mut self){
self.elems.push("a".to_string());
self.elems.push("b".to_string());
self.elems.push("c".to_string());
let strings = &self.elems[..3];
let new_pack= Container{contains: vec![&strings[0],&strings[1],&strings[2]]};
self.packages.push(new_pack); // error: lifetime may not live long enough
}
}
The error message is :
error: lifetime may not live long enough
--> src/lib.rs:82:9
|
68 | impl<'a> Space<'a> {
| -- lifetime `'a` defined here
...
76 | pub fn increase(&mut self){
| - let's call the lifetime of this reference `'1`
...
82 | self.packages.push(new_pack);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`
To fix this problem, rewrite as
pub fn increase(&'a mut self){
self.elems.push("a".to_string());
self.elems.push("b".to_string());
self.elems.push("c".to_string());
let strings = &self.elems[..3];
let new_pack= Container{contains: vec![&strings[0],&strings[1],&strings[2]]};
self.packages.push(new_pack);
}
then , this newly introduced lifetime 'a makes the instance of 'Space' cannot be changed anymore.
mod tests{
use crate::Space;
// #[test]
fn test_space(){
let mut new_space = Space::new();
new_space.increase();
new_space.increase(); // error message : cannot borrow `new_space` as mutable more than once at a time
}
}
error message:
error[E0499]: cannot borrow `new_space` as mutable more than once at a time
--> src/lib.rs:93:9
|
92 | new_space.increase();
| -------------------- first mutable borrow occurs here
93 | new_space.increase();
| ^^^^^^^^^^^^^^^^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
So the common mistake is trying to maintain a set of data and reference of this data in the same structure and hope there is a method that could introduce new data to that structure.