Reputation: 11
I am struggling to find a way on how to solve following problem in Rust. I want to be able to loop over a (mutable) vector and still be able to loop over the same vector nested in the outer one.
struct Test {
value: i32,
}
fn main() {
let mut vec = [Test{value: 1}, Test{value: 2}, Test{value: 3}];
for el in vec.iter_mut(){
println!("{}", el.value);
for a in vec.iter_mut(){
println!("Inner {}", a.value);
}
el.value = 10;
}
}
is resultin in an error caused by the borrow checker:
error[E0499]: cannot borrow `vec` as mutable more than once at a time
--> src\main.rs:12:18
|
9 | for el in vec.iter_mut(){
| --------------
| |
| first mutable borrow occurs here
| first borrow later used here
...
12 | for a in vec.iter_mut(){
| ^^^ second mutable borrow occurs here
Upvotes: 0
Views: 86
Reputation: 793
Assuming Test
can be copy, this is achievable by using std::cell::Cell
: (playground)
use std::cell::Cell;
#[derive(Debug, Copy, Clone)]
struct Test {
value: i32,
}
fn main() {
let mut vec = [Test{value: 1}, Test{value: 2}, Test{value: 3}];
let vec: &Cell<[Test]> = Cell::from_mut(vec.as_mut_slice());
let vec: &[Cell<Test>] = vec.as_slice_of_cells();
for el in vec.iter() {
for a in vec.iter() {
// use `a`
dbg!(a.get().value);
}
// Mutate
el.set(Test {value: 10});
}
}
If Test
is not copy, this method can still be used, but unsafe may be necessary.
Upvotes: 1
Reputation: 96547
Yeah you can't do that, even though it does seem almost reasonable (if you dropped el
before the inner loop at least). I think the fundamental issue is that Rust doesn't distinguish between your mutable access to the elements of vec
, and vec
itself (e.g. to change its length).
It doesn't actually know that vec.iter_mut()
isn't going to remove or reorder elements. And if it did, that would obviously break the outer loop.
Depending on what you want to do you can do it using indexes (in C style), or maybe by manipulating iterators.
Upvotes: 1