Sorting a vector of tuples requires a reference for the second value?

I have a vector of tuples of integers and you want to sort it by the second element of each tuple:

fn main() { let mut tuple_list2: Vec<(u16, u16)> = vec![(1, 5), (0, 17), (8, 2)]; tuple_list2.sort_by(|a, b| a.1.cmp(b.1)); } 

The compiler throws an error because b.1 is u16 and not a reference to one ( &u16 ). I can solve this problem by specifying b.1 instead:

 fn main() { let mut tuple_list2: Vec<(u16, u16)> = vec![(1, 5), (0, 17), (8, 2)]; tuple_list2.sort_by(|a, b| a.1.cmp(&b.1)); } 

I do not understand why I should do this. Moreover, I do not need to refer to a.1 .

+6
source share
1 answer

As already mentioned in the comments of Aurora0001, we should take a look at the signature of the cmp() function :

 fn cmp(&self, other: &Self) -> Ordering 

We see that both values ​​are taken by reference, so it should not be a surprise that you should pass &b.1 method instead of b.1 .

Moreover, I do not need to refer to a.1 .

This is a more interesting question ;-)

A simple solution is that of an operator . (dot) performs automatic dereferencing as well as auto-plotting. Look at this in action:

 struct Foo; impl Foo { fn takes_value(self) {} fn takes_ref(&self) {} fn takes_mut_ref(&mut self) {} } fn main() { let mut a = Foo; // all of those work thanks to auto-borrowing a.takes_ref(); a.takes_mut_ref(); a.takes_value(); // -------- let b = Foo; let c = &mut b; // these work as well c.takes_ref(); c.takes_mut_ref(); // this one works, *if* the type implements `Copy` c.takes_value(); } 

So the operator . helps the programmer and always passes the correct type of self parameter.


Note : the sorting you do very often. There is an even more suitable method for this task: [T]::sort_by_key() . It will look like this:

 // note: type annotations not required let mut tuple_list2 = vec![(1, 5), (0, 17), (8, 2)]; tuple_list2.sort_by_key(|k| k.1); 
+7
source

All Articles