Let's write a poor man's mutable iteration.
let mut v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let v_len = v.len();
for index in 0..v_len {
v[index] *= 2;
}
Dummy, useless but it works.
Let's use a functional approach:
(0..v_len).for_each(|index| {
v[index] *= 2;
});
Everything fine!
Now what I expected to work but it does not.
(0..v_len).map(|index| &mut v[index]).for_each(|el| {
*el *= 2;
});
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:14:27
|
14 | .map(|index| &mut v[index])
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime as defined on the body at 14:14...
--> src/main.rs:14:14
|
14 | .map(|index| &mut v[index])
| ^^^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `v`
--> src/main.rs:14:27
|
14 | .map(|index| &mut v[index])
| ^
note: but, the lifetime must be valid for the expression at 16:13...
--> src/main.rs:16:13
|
16 | *el *= 2;
| ^^^
note: ...so that pointer is not dereferenced outside its lifetime
--> src/main.rs:16:13
|
16 | *el *= 2;
| ^^^
I really tried to understand what was going on, but I did not figure it out. I imagined that I needed to move
the slice inside the closure, but it does not change anything.
So:
- can you help me understand what the real issue is?
- do you have any idea if there is a workaround?
Just a quick note: there is a reason for using indices. I found myself needing the mutable reference of two distinct elements inside a slice. That can be easily (more or less) done using split_at_mut
and split_first_mut
, obtaining a mut ref to an element and two mutable slices, from which another element can be taken. I wanted to return an impl Iterator
that returns pairs of mutable reference that satisfy certain conditions, but the error I showed you is blocking me. Even worse, it is not possible to create a custom iterator that performs that because it would require streaming iterators, therefore a stable implementation of GAT.