对元组向量进行排序需要第二个值的引用吗?

时间:2016-10-17 16:16:05

标签: sorting vector reference rust tuples

我有一个整数元组的向量,想要按每个元组的第二个元素对它进行排序:

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));
}

编译器抛出错误,因为b.1u16而不是对&u16的引用。我可以通过引用b.1来解决此问题:

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));
}

我不明白我为什么要这样做。特别是因为我不需要引用a.1

1 个答案:

答案 0 :(得分:9)

正如Aurora0001已经在评论中指出的那样,我们应该看看the function signature of cmp()

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

我们发现这两个值都是通过引用获取的,因此您必须将&b.1传递给方法而不是b.1,这不足为奇。

  

特别是因为我不需要引用a.1

这是一个更有趣的问题;-)

简单的解决方案是,.(点)运算符执行自动解除引用以及自动借用。让我们看看它的实际效果:

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();
}

因此.运算符可以帮助程序员并始终传递正确的self参数。

注意:你做的排序很常见。有一种方法更适合这项任务:[T]::sort_by_key()。它看起来像这样:

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