【问题标题】:Why I can use sort_by_key with a Vec?为什么我可以将 sort_by_key 与 Vec 一起使用?
【发布时间】:2016-04-05 21:27:16
【问题描述】:

举个例子

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

我觉得这很酷

【问题讨论】:

  • 我完全无法理解这个问题——你可以重写它的一些组件吗?
  • @ᅵZVᅵ 我更新了希望你能理解的更好。谢谢

标签: rust


【解决方案1】:

正如 Jascha 所提到的,Vec&lt;T&gt; 实现了 Deref&lt;Target=[T]&gt;DerefMut

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

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

    // ..
}

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

这反过来意味着当解析一个类型的方法时,编译器可以轻松地应用deref coercions。也就是说,只要没有找到给定名称的方法,它就可以查看当前类型是否可以再次取消引用并重试(是的,可以链接)。


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

  • &amp;mut Vec&lt;T&gt; 上寻找sort_by_key,没有
  • &amp;mut [T] 上寻找sort_by_key,它存在

然后它将调用转换为:

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

进入:

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

自动。

【讨论】:

  • 非常感谢您的解释,现在可以更好地了解它是如何工作的
  • 我在想也许把标题放在“为什么我可以将 sort_by_key 与 Vec 一起使用?( Deref )”但以前不知道,也许如果添加这个词,会使其他人更容易访问您和其他人在此问题中详述的信息。但是不知道把这个加到标题上好不好?
  • @AngelAngel:我不知道:x
  • @AngelAngel 不,它没有用。将Deref 放在标题中将要求人们在能够提出问题之前知道答案
  • @Shepmaster 感谢您的回答,我也是这么想的,所以我问这个。但是,如果有人正在寻找有关 Defer 的信息,他们可以通过某种方式访问​​此信息,但您说的没错,感谢您的宝贵时间
【解决方案2】:

Vec&lt;T&gt; 实现 Deref&lt;Target=[T]&gt;[T] 是一个切片)。你可以找到更多关于 deref coercions here。 API 文档甚至列出了所有可通过Deref 访问的methods

【讨论】:

  • 我在这 -> doc.rust-lang.org/collections/vec/struct.Vec.html 你放的链接更详细,谢谢。我和寻找 rust/vec.rs 现在看到 deref 和我看更多关于它感谢您的时间。
  • 你可以帮帮我,我真的看不懂文档(我的英语不是很好),我可以理解使用 Deref,实现 Deref 的结构可以访问它适用的方法, 在这种情况下是切片,但它可能是另一个
猜你喜欢
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
  • 2010-09-12
  • 2019-06-19
  • 1970-01-01
相关资源
最近更新 更多