这是标准说的:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
和链接:https : //doc.rust-lang.org/src/core/cmp.rs.html#207
这是我的代码:
fn main() {
let a = 1;
let b = &a;
println!("{}", a==b);
}
Run Code Online (Sandbox Code Playgroud)
编译器告诉我:
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}`
Run Code Online (Sandbox Code Playgroud)
但是当我使用“eq()”时,它可以被编译:
fn main() {
let a = 1;
let b = &a;
println!("{}", a.eq(b));
}
Run Code Online (Sandbox Code Playgroud)
其实很简单,但是需要一点知识。表达式a == b是语法糖PartialEq::eq(&a, &b)(否则,如果我们处理非类型,我们将移动a并b尝试测试它们是否相等Copy)。
在我们的例子中,该函数PartialEq::eq需要接受两个参数,这两个参数的类型都是&i32。我们看到了a : i32和b : &i32。因此,&b将有 type &&i32,而不是 &i32。
通过尝试比较具有不同类型的两个事物,我们会得到类型错误,这是有道理的。ahas typei32并且bhas type &i32,所以无论编译器如何秘密实现a == b,我们都可能会因为尝试这样做而得到类型错误。
另一方面,在 where 的情况下a : i32,表达式a.eq(b)是 的语法糖PartialEq::eq(&a, b)。这里有一个微妙的区别 - 没有&b. 在这种情况下,&a和b都有 type &i32,所以这完全没问题。
小智 5
a.eq(b)和之间的区别a == b在于,点运算符对按引用调用方法的接收器类型执行 autoref/autoderef。
因此,当您编写a.eq(b)编译器时PartialEq::eq(&self, other: &Rhs),它会查看签名、查看&self引用并将其添加到a.
当您将a == b其写为脱糖到您的PartialEq::eq(a, b)情况a: i32 b: &i32时,因此会出现错误no implementation for `{integer} == &{integer}` 。
但为什么它在运算符中不做同样的事情呢?请参阅 跟踪问题:允许在运算符中使用 autoderef 和 autoref(实验)#44762
相关信息: Rust 的确切自动解除引用规则是什么?
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |