I want to write a function which takes an Iterator<Item = &mut u32>
and iterates it repeatedly (the function implements some sort of iterative algorithm). Seems fairly straightforward, but I've been struggling with this for long enough that I'm starting to doubt whether that's even possible. I'll share below what I have tried so far, but it's well possible that I ran off in the wrong direction, in which case you may feel free to ignore my rambling and just show me how it's done.
Since iterators can't be restarted, and since iterators over mutable data can't possibly implement Clone
, I thought I could achieve what I wanted by letting the function take an iterator-generating function as input, i.e. I thought I could do something akin to the following.
fn foo<'a, Iter>(mut iter: impl FnMut() -> Iter)
where
Iter: Iterator<Item = &'a mut u32>,
{
// Dummy function body
for _ in 0..3 {
for v in iter() {
*v = 42;
}
}
}
Unfortunately, I get the following error when I try to call this function.
|
13 | let mut vec = vec![1, 2, 3];
| ------- variable defined here
14 | foo(|| vec.iter_mut());
| - ---^^^^^^^^^^^
| | |
| | returns a reference to a captured variable which escapes the closure body
| | variable captured here
| inferred to be a `FnMut` closure
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
I understand that what I've written can't work (there's no lifetime restriction on the return value of the closure, so if this were to compile then I could generate an arbitrary number of mutable references to the same data by calling the closure repeatedly), but I'm not sure how to fix it. The only solution I can think of would be to introduce my own trait which mimics the FnMut
trait but allows me to restrict the lifetime of the return value, but that's starting to sound complicated enough that the cure might be worse than the disease. Isn't there a simpler way to do this in Rust?