for my programm I want to fill a vector with arrays containing integers, but at some point I might want to manipulate the last entry in the vector if present. I aim to perform this efficiently as possible. So I thought to do it in the following way. I tried to change the code and get it working, but I failed so far. I hope someone can help me, so I provided a minimum example I work on to understand the issue.
fn main() {
let mut test_vec: Vec<[i8; 3]> = vec![];
test_vec.push([1, 2, 3]);
test_vec.push([4, 5, 6]);
match test_vec.last() {
Some(v) => {
v[2] = 0; // this does not work <= need help!
}
None => {}
}
test_vec.push([7, 8, 9]);
match test_vec.last() {
Some(v) => {
v[1] = 0; // this also fails <= need help!
}
None => {}
}
for entry in test_vec {
println!("{entry:?}"); // should print [1, 2, 3], [4, 5, 0] and [7, 0, 9]
}
}
[T]::last
returns Option<&T>
. This is shared reference, which cannot be used to modify pointed to data. Use [T]::last_mut
, which returns Option<&mut T>
.
fn main() {
let mut test_vec: Vec<[i8; 3]> = vec![];
test_vec.push([1, 2, 3]);
test_vec.push([4, 5, 6]);
if let Some(v) = test_vec.last_mut() {
v[2] = 0;
}
test_vec.push([7, 8, 9]);
if let Some(v) = test_vec.last_mut() {
v[1] = 0;
}
for entry in test_vec {
println!("{entry:?}"); // prints [1, 2, 3], [4, 5, 0] and [7, 0, 9]
}
}
Note that Rust compiler tries to suggest this solution, by telling you to change binding from &[...]
to &mut [...]
.
error[E0594]: cannot assign to `v[_]`, which is behind a `&` reference
--> src/main.rs:7:13
|
6 | Some(v) => {
| - consider changing this binding's type to be: `&mut [i8; 3]`
7 | v[2] = 0;
| ^^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written