I have trouble solving an obvious simple problem.
Basically I want to push an instance of a structure to a vector to get it out later and to modify the object by calling a function implemented for the structure.
To simplify the case, I created the following test code, which reflects in my opinion to the same problem.
let mut strings = Vec::new();
strings.push("Hello".to_string());
let string_option = strings.last();
let string = string_option.unwrap();
string.shrink_to(1);
This has the compile error
error[E0596]: cannot borrow `*string` as mutable, as it is behind a `&` reference
--> src/main.rs:89:5
|
88 | let string = string_option.unwrap();
| ------ help: consider changing this to be a mutable reference: `&mut String`
89 | string.shrink_to(1);
| ^^^^^^^^^^^^^^^^^^^ `string` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Then I tried sheer endless variants like
let mut strings = Vec::new();
strings.push("Hello".to_string());
let string_option = strings.last().as_mut();
let string = string_option.unwrap();
string.shrink_to(1);
... or ...
let mut strings = Vec::new();
strings.push("Hello".to_string());
let string_option = strings.last().as_deref_mut();
let string = string_option.unwrap();
string.shrink_to(1);
Actually the code shown above is a simplification from this code, which I originally wanted to do.
struct Bar {
data: Vec<String>
}
impl Bar {
fn shrink_first(&mut self) {
let s_opt = self.data.last().as_mut(); // s_opt is of type Option<&mut &String>
let s = s_opt.unwrap(); // s is of type &mut & String
s.shrink_to(1);
}
}
The code above brings the following errors ...
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:67:21
|
67 | let s_opt = self.data.last().as_mut(); // s_opt is of type Option<&mut &String>
| ^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
68 |
69 | let s = s_opt.unwrap(); // s is of type &mut & String
| ----- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
error[E0596]: cannot borrow `**s` as mutable, as it is behind a `&` reference
--> src/main.rs:70:9
|
70 | s.shrink_to(1);
| ^^^^^^^^^^^^^^ cannot borrow as mutable
But in my opinion it always has the same root causes, but I have not figured out what to do.
Simply change strings.last()
to strings.last_mut()
.
The last()
method returns a standard (immutable) reference (to be more precise, Option<&T>
).
To be able to mutate the last String
in the vector, you need to get a mutable reference via last_mut()
.