error[E0382]: use of moved value: `errors`
--> src/main.rs:14:21
|
2 | let mut errors = vec![];
| ---------- move occurs because `errors` has type `Vec<(&str, &i16)>`, which does not implement the `Copy` trait
...
5 | let result = events.iter().map(move |event| match event {
| ------------ value moved into closure here
...
8 | errors.push(("some_error", offset));
| ------ variable moved due to use in closure
...
14 | rerender_errors(errors);
| ^^^^^^ value used here after move
The move in move |event| match event { is telling the compiler that the closure takes ownership of any captured value (in this case only errors). However you don't want it to take ownership because you want to still use it afterwards. The fix is easy, just remove the move keyword.
Iterator::map is lazy, it won't do anything until you iterate the resultin iterator using a for loop or the for_each/fold/collect/ecc ecc methods.
My example started working however in my real world scenario I'd need to pass uncollected iterator so my next function for result would need to get Iterator<T> is there any way to avoid collecting or convert back to iterator after consuming values?
You can't get back the original iterator after consuming its values. You could clone the original iterator before iterating through it, but this is not always possible, might introduce some bugs if the iterator is doing non-trivial work and might also be more expensive than collecting in a Vec.
If you just need an Iterator<Item = T> instead of `Iterator<Item = Result<T, E>> and you're ok with delaying the handling of the errors after iterating through it, then you can use something like itertools::process_results - Rust
it seems like I would need both - Vec Result to display errors and I: Iterator<Item = T<'a>> to render results, learned that fold is returning Results for both cases, is it possible to make it working?
Either change render_result to take an impl IntoIterator<Item = &str> or change the rerender_errors(errors); call into rerender_errors(errors.iter().copied()); (the copied is there because otherwise the items would have type &&str instead of &str)
it solves borrow in closure issue and allows to consume results with mapping over events list.
Thank you for explaining Iterator and lazy map, however I still don't fully understand why my fix works.
The error you get in the first case is because when you call render_errors(errors), you move the errors vector to the rerender_errors function, giving up ownership, and any borrow of errors become invalid at that point. But then you try to print result, and result holds a borrow of errors (within the map closure). Because the borrow is invalid at that point, you get the error.
If you instead print result before the function call, you avoid such a "borrow used after move".
In both cases, you still aren't actually iterating your iterator, just printing out it's debug representation.