Why do the vector values not get move to the Ordering function in the below code?

I am a Rust noob and I have been going through a few videos and articles. I was following this article here about Rust iterators.

When it is explaining iter_mut() it uses the following example.

fn main() {
    let mut teams = [
        [ ("Jack", 20), ("Jane", 23), ("Jill", 18), ("John", 19), ],
        [ ("Bill", 17), ("Brenda", 16), ("Brad", 18), ("Barbara", 17), ]
    ];

    let teams_in_score_order = teams
        .iter_mut()
        .map(|team| {
            team.sort_by(|&a, &b| a.1.cmp(&b.1).reverse());
            team
        })
        .collect::<Vec<_>>();
    
    println!("Teams: {:?}", teams_in_score_order);
}

Here team.sort_by(|&a, &b| a.1.cmp(&b.1).reverse()) VS Code tells me that these are the variable types.

   a: (&str, i32)
   b: (&str, i32)

So here in the closure a.1.cmp(&b.1).reverse(), a is not a borrowed value (according to my current understanding). So why wouldn't it get dropped at the end of the closure? I am assuming, that if a gets dropped, then there would not be any items left in the vector at the end of this function. One more question: Once a value is passed as a borrowed value, what does it mean to access without the &?

Also, I was trying to understand, defining closure parameters using &. I understand & means to reference/borrow a value. However here, I removed & from |&a, &b| and it still worked, but at that point, types were defined as a: &(&str, i32) b: &(&str, i32). Here what does it mean by having or not having & in the parameter definition in |&a, &b|?

Thanks in advance!


It does not get moved because (&str, i32) implements Copy (as both &str and i32 both implement Copy), so instead of moving it just copies the tuple.

You can test this by trying to compile this:

fn main() {
    let mut teams = [
        [ ("Jack".to_owned(), 20), ("Jane".to_owned(), 23), ("Jill".to_owned(), 18), ("John".to_owned(), 19), ],
        [ ("Bill".to_owned(), 17), ("Brenda".to_owned(), 16), ("Brad".to_owned(), 18), ("Barbara".to_owned(), 17), ]
    ];

    let teams_in_score_order = teams
        .iter_mut()
        .map(|team| {
            team.sort_by(|&a, &b| a.1.cmp(&b.1).reverse());
            team
        })
        .collect::<Vec<_>>();
    
    println!("Teams: {:?}", teams_in_score_order);
}

Rust Playground

The compiler will now complain that it is being moved, since the type is now (String, i32), and String does not implement Copy.

Also, I was trying to understand, defining closure parameters using &.

I believe using & when defining arguments in a closure is just sugar for the de-referencing each variable. E.g.

|&a, &b| a.1.cmp(&b.1).reverse()

is the same as

|a, b| { 
    let a = *a;
    let b = *b;
    
    a.1.cmp(&b.1).reverse()
}

Though I am not 100% sure this is correct.