Does this solution for handling &mut in multiple Iterator closures already exist in a crate somewhere?

Hi Folks,

I finally found a solution tonight to a nagging problem I ran into using &mut with multiple Iterator closures in same function. Wanted to see if anyone knows if this solution either already exists in a crate or if there is some better/more idiomatic way of doing this already.

Thanks!

Failure case:

    let v = vec!["1".to_string(),"2".to_string(),"3".to_string()];
    let mut x = 4;
    let m = &mut x;

    let result : Vec<String> =
        v.into_iter()
            .map(|s|{
                *m += 1;
                ((s.parse::<i32>().unwrap()) + *m).to_string()
            })
            // 2nd .map closure here fails borrow checker, m already borrowed
//                .map(|s|{
//                    *m += 1;
//                    ((s.parse::<i32>().unwrap()) + *m).to_string()
//                })
            .collect::<Vec<String>>();

A solution:

    let v = vec!["1".to_string(),"2".to_string(),"3".to_string()];
    let mut x = 0;
    let m = &mut x;

    let result : Vec<String> =
        v.into_iter()
            .with_mut::<i32>()
            .map(|m,s|{
                *m += 1;
                ((s.parse::<i32>().unwrap()) + *m).to_string()
            })
            .map(|m,s|{
                *m += 1;
                ((s.parse::<i32>().unwrap()) + *m).to_string()
            })
            .bind_mut(m)
            .collect::<Vec<String>>();

Playground:

You could also try

std::iter::from_fn(|| Some(&mut m))
    .zip(iter)
    .map(|(m, x)| ...)
    .map(|(m, x)| ...)
    ...

Note, I have not tested this code

Hi Krishna, thanks for the response. Your solution is much cleaner and simpler than mine. Sadly though it doesn't pass borrow checker: can't move &mut out of a closure once it has been borrowed.

Playground:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.