Reputation: 327
fn main() {
// i passed a reference to a value of type i32
print_type_of(&1); // but print: i32
// but if i pass a double reference
print_type_of(&&1); // it print &i32, not &&i32
// i passed a referece to a value of type i32
print_type_of_without_ampersand(&1); // now print: &i32 as expected
referece_pattern(&1); // it works!
// -> update <-
// if i have
let x = 1;
let ref_x = &&x;
// this is the implementation of Deref for &T
// #[stable(feature = "rust1", since = "1.0.0")]
// #[rustc_const_unstable(feature = "const_deref", issue = "88955")]
// impl<T: ?Sized> const Deref for &T { //! -> here T should be &&i32 or &i32 ? <- !
// type Target = T;
// #[rustc_diagnostic_item = "noop_method_deref"]
// fn deref(&self) -> &T { // if here self is &&i32, and T should be &&i32 too
// *self // <- here after deference self should be &i32, but &T is still &&i32 that is incompatible <- !
// }
// }
// -> end update <-
}
// amperand is before the type name
// so it should not be a reference pattern
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn print_type_of_without_ampersand<T>(_: T) {
println!("{}", std::any::type_name::<T>())
}
// reference pattern happens here
// amperand is before the parameter name
fn referece_pattern(&x: &i32) {
assert!(x == 1);
println!("it works!");
}
I also read this article on reference patterns,but it doesn't explain this.
update: I added new content in the code, about implementation of Deref for &T
Upvotes: 0
Views: 73
Reputation: 27248
Not really sure where the confusion is.
fn print_type_of<T>(_: &T);
is a function with a type parameter T
which receives a reference to T
(&T
)
so if you give it a &i32
the type that reference 'points' to is i32
so when you later call
type_name::<T>()
you get i32
because that's what T
is.
If T
resolved to &i32
like you seem to be expeting then it would expect an item of type &&i32
.
No reference pattern just the way the types check out once you do the substitution.
Upvotes: 4