This is what the std says:
pub trait PartialEq<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used
/// by `==`.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn eq(&self, other: &Rhs) -> bool;
/// This method tests for `!=`.
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
}
And the link: https://doc.rust-lang.org/src/core/cmp.rs.html#207
This is my code:
fn main() {
let a = 1;
let b = &a;
println!("{}", a==b);
}
and the compiler told me:
error[E0277]: can't compare `{integer}` with `&{integer}`
--> src\main.rs:4:21
|
4 | println!("{}", a==b);
| ^^ no implementation for `{integer} == &{integer}`
|
= help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}`
But when I used eq()
, it compiled:
fn main() {
let a = 1;
let b = &a;
println!("{}", a.eq(b));
}
It's actually quite simple, but it requires a bit of knowledge. The expression a == b
is syntactic sugar for PartialEq::eq(&a, &b)
(otherwise, we'd be moving a
and b
by trying to test if they're equal if we're dealing with non- Copy
types).
In our case, the function PartialEq::eq
needs to take two arguments, both of which are of type &i32
. We see that a: i32
and b: &i32
. Thus, &b
will have type &&i32
, not &i32
.
It makes sense that we'd get a type error by trying to compare two things with different types. a
has type i32
and b
has type &i32
, so it makes sense that no matter how the compiler secretly implements a == b
, we might get a type error for trying to do it.
On the other hand, in the case where a: i32
, the expression a.eq(b)
is syntactic sugar for PartialEq::eq(&a, b)
. There's a subtle difference here - there's no &b
. In this case, both &a
and b
have type &i32
, so this is totally fine.
The difference between a.eq(b)
and a == b
in that dot operator does autoref/autoderef on receiver type for call-by-reference methods.
So when you write a.eq(b)
compiler looks at PartialEq::eq(&self, other: &Rhs)
signature, sees &self
reference and adds it to a
.
When you write a == b
it desugars to PartialEq::eq(a, b)
where a: i32
b: &i32
in your case, hence the error no implementation for `{integer} == &{integer}`
.
But why it does not do the same in operators? See Tracking issue: Allow autoderef and autoref in operators (experiment) #44762
Related information: What are Rust's exact auto-dereferencing rules?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.