Reputation: 21728
Taking this example
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());
}
I searched the source code for Vec
, but I do not see a trait or something like derive
.
trait SomeTrait {
fn sort_by_key...
}
impl SomeTrait for Vec... { }
The IntelliSense of my IDE did not detect sort_by_key
either.
I searched the Rust Github and found 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)))
}
But I can not see how Vec
relates to a slice and how Vec
can access sort_by_key
.
I saw this constructor in vec.rs
:
pub fn new() -> Vec<T> {
Vec {
buf: RawVec::new(),
len: 0,
}
}
I navigated the struct
but I fail to understand where sort_by_key
comes from.
After the response by Jascha
I can not understand the documentation as my English is not very good. I understand that by using Deref
, the struct that implements Deref
can access methods to which it applies, in this case a slice, but it could be another?
I found this url which helps me understand my follow up question and may help others:
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();
}
I think this is very cool
Upvotes: 5
Views: 4087
Reputation: 300099
As Jascha mentioned, Vec<T>
implements Deref<Target=[T]>
and DerefMut
.
Note the specific syntax here: Target
is an associated type of Deref
(not an input) and the implementation looks like:
impl<T> Deref for Vec<T> {
type Target = [T];
// ..
}
The fact that Target
is an associated type of Deref
is important, because it means that Deref
can only ever be implemented once for any given (concrete) type.
This, in turns, means that when resolving methods on a type, the compiler can easily apply deref coercions. That is, as long as no method of the given name is found, it can see if the current type can be deref'ed once more and try again (yes, this can be chained).
In the current situation this means the compiler:
sort_by_key
on &mut Vec<T>
, there is nonesort_by_key
on &mut [T]
, it existsit then transforms the call from:
let mut v = vec![1, 3, 2];
v.sort_by_key(...);
into:
let mut v = vec![1, 3, 2];
(&mut *v).sort_by_key(...);
automatically.
Upvotes: 11