Reputation: 33
Here is segment I've a problem with, basically just pushing a &str to Vec<&str> in the loop
fn main() {
let mut accounting = vec!["Alice", "Ben"];
loop {
let mut add_input = String::from("");
io::stdin()
.read_line(&mut add_input)
.expect("Failed to read line");
let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect();
if add_vec.len() < 1 {
println!("Incorrect input, try again");
continue;
}
let person = add_vec[0];
accounting.push(person);
}
}
let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect();
- here's where I get "borrowed value does not live long enough".
I was able to make my code work by changing target vector signature from Vec<&str>
to Vec<String>
and pushing not a &str but &str.to_string()
I understand that pushing a &str bacibally making it invalid to for the scope that .push was called in, but while that is happening right at the end of the loop - why is that a problem?
The error give is:
$ rustc main.rs
error[E0597]: `add_input` does not live long enough
--> main.rs:14:34
|
14 | let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect();
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
22 | accounting.push(person);
| ----------------------- borrow later used here
23 | }
| - `add_input` dropped here while still borrowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
Upvotes: 3
Views: 520
Reputation: 14820
first you create i vec
in you main
method. It will have the lifetime of the brackets surrounding the `main function.
fn main {
// accounting has a lifetime between these 2 brackets.
let mut accounting = vec!["Alice", "Ben"];
}
Later you create a new vec
containing references inside the loop
.
fn main {
loop {
// add_vec has a lifetime between the loop brackets
let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect();
}
}
That vec
has lifetime between the loop
bracket. Since that vec contains &str
it only contains references to slices of strings that are most likely stored on the stack that is accessible between the loop brackets.
Later in your code you want to add this vec of &str
to the outer vec
. Its here we will get a problem. The problem is that when we exit the loop the str
will get dropped, and what is left will be a vec
with a lot of references that are not referencing something.
Hence your error:
borrowed value does not live long enough
The borrowed value (&str
) between the loop brackets wont live long enough to be stored outside the brackets.
fn main {
loop {
// If you create something on the stack between these brackets
} <--- it will get dropped here
}
So one solution here is if you want to design your code this way is that you instead from using &str
switch to using String
which will allocate memory on the heap for the string instead. This means the string won't get dropped when we exit the loop brackets.
But remember by allocating memory like that your program will consume more memory which is not always feasible (if you are in a memory constrained platform like for instance embedded)
Upvotes: 2