为什么我可以使用带有Vec的sort_by_key?

时间:2016-04-05 21:27:17

标签: rust

以此为例

fn main() {

    let mut test: Vec<u32> = Vec::new(); 

    test.push(5);
    test.push(8);
    test.push(0);

    test.sort_by_key(|k| k.abs());
}

我搜索the source code for Vec,但我没有看到derive等特征。

trait SomeTrait {
    fn sort_by_key...
}

impl SomeTrait for Vec... { }

我的IDE的IntelliSense也没有检测到sort_by_key

我在Rust Github上搜索了this implementation in slice.rs

pub fn sort_by_key<B, F>(&mut self, mut f: F)
    where F: FnMut(&T) -> B, B: Ord
{
    self.sort_by(|a, b| f(a).cmp(&f(b)))
}

但我无法看到Vec与切片的关系以及Vec如何访问sort_by_key

我在vec.rs中看到了这个构造函数:

pub fn new() -> Vec<T> {
    Vec {
        buf: RawVec::new(),
        len: 0,
    }
} 

我浏览了struct,但我无法理解sort_by_key的来源。

response by Jascha

之后

我无法理解文档,因为我的英语不是很好。我理解通过使用Deref,实现Deref的结构可以访问它应用的方法,在这种情况下是一个切片,但它可能是另一个?

我发现this url可以帮助我理解我的后续问题,并可以帮助其他人:

struct Foo;
impl Foo {
     fn foo(&self) { }
}

struct Bar {
    foo: Foo,
}

impl std::ops::Deref for Bar {
     type Target = Foo;

    fn deref(&self) -> &Foo {
        &self.foo
    }
}

fn main() {
    let test: Bar = Bar { foo: Foo }; 
    test.foo();  
}

我觉得这很酷

2 个答案:

答案 0 :(得分:7)

正如Jascha所说,Vec<T>实现了Deref<Target=[T]>DerefMut

请注意这里的具体语法:TargetDeref的关联类型(不是输入),实现如下:

impl<T> Deref for Vec<T> {
    type Target = [T];

    // ..
}

TargetDeref的关联类型这一事实很重要,因为这意味着任何给定的Deref 只能实施一次(具体)类型。

这反过来意味着在解析类型上的方法时,编译器可以轻松应用 deref强制。也就是说,只要找不到给定名称的方法,它就可以看到当前类型是否可以再次进行deref'ed并重试(是的,这可以链接)。

在目前的情况下,这意味着编译器:

  • sort_by_key上查找&mut Vec<T>,没有
  • sort_by_key上查找&mut [T],它存在

然后转换来自:

的电话
let mut v = vec![1, 3, 2];
v.sort_by_key(...);

成:

let mut v = vec![1, 3, 2];
(&mut *v).sort_by_key(...);

自动

答案 1 :(得分:3)

Vec<T>实现Deref<Target=[T]>[T]是一个切片)。您可以找到有关deref强制here的更多信息。 API文档甚至列出了Deref可访问的所有methods