Imperative vs functional : cannot move out of a shared reference

Hello,
I understood that using iterators is idiomatic in Rust, but I face a problem.
In the imperative code, it works fine, but in the functional one, m is now a reference, and I can't dereference it like in the comment, or I get the error: cannot move out of *m which is behind a shared reference.

Note that in the end, I want a Vec<MsgSpec>.

imperative style:

let msg_errs_tuples: Vec<(MsgSpec, String)> = ... ;

let mut msgs = vec![];
let mut errs = vec![];
for (m, e) in msg_errs_tuples {
    msgs.push(m);
    errs.push(e);
}

functional style:

let msg_errs_tuples: Vec<(MsgSpec, String)> = ... ;

let (msgs, errs) = msg_errs_tuples.iter()
    .fold((Vec::<MsgSpec>::new(), Vec::new()), |(mut msgs, mut errs), (m, e)| {
//        let a:MsgSpec = *m;
        msgs.push(*m);
        errs.push(e);
        (msgs, errs)
    });

Can someone explain me what's going on here ?

Thanks

Use the into_iter method instead of iter. More details here.

.iter() borrows the vector and yields references to its contents.

.into_iter() consumes the vector and yields its concepts by value. The for loop is equivalent to calling into_iter.

1 Like

Oh thanks ! That was so simple !

So if I understood well:
with iter() I had a reference to the tuple, so I could not move its content.
with into_iter() I a really have the tuple, so I can do whatever I want with its content.

That's it ?

Thank you again !

1 Like

Yes, that's exactly correct.