21、Operator overloading(运算符重载)
运算符重载
现在我们对于traits有了基本的了解,回到运算符重载上来。运算符重载就是对一些运算符(比如+,-,*,/,==,!=等)的行为进行自定义。
运算符是traits
在Rust里,运算符就是traits。
对于每一个运算符,都有相应的trait来定义这个运算符的行为。通过对我们自己的类型实施这个trait,我们就可以解锁响应运算符的用法。
例如,PartialEqtrait定义了==和!=的行为:
// The `PartialEq` trait definition, from Rust's standard library
// (It is *slightly* simplified, for now)
pub trait PartialEq {
// Required method
//
// `Self` is a Rust keyword that stands for
// "the type that is implementing the trait"
fn eq(&self, other: &Self) -> bool;
// Provided method
fn ne(&self, other: &Self) -> bool { ... }
}
当我们编写x==y的时候,编译器会为x和y的类型寻找PartialEqtrait的实现,并将x==y替换为x.eq(y)。这就是语法糖!
这是基本操作符与trait的对应关系
算术运算符位于std::ops模块当中,而比较运算符位于std::cmp模块当中。
默认实现

PartialEq的注释指出“ne是一个提供的方法(ne is a provided method)”
这句话的意思就是PartialEq在trait定义中,为ne提供了一个默认实现,就是定义片段中{…}这个省略块
可以看到就是上面的源代码:
pub trait PartialEq {
fn eq(&self, other: &Self) -> bool;
fn ne(&self, other: &Self) -> bool {
!self.eq(other)
}
}
这正是我们预料到的,ne就是eq的否定。
因为eq提供了默认实现,所以在为我们的自定义类型实现PartialEq的时候可以跳过ne,只实现eq即可。
比如下面这个例子:
struct WrappingU8 {
inner: u8,
}
impl PartialEq for WrappingU8 {
fn eq(&self, other: &WrappingU8) -> bool {
self.inner == other.inner
}
// No `ne` implementation here
// 这里没有`ne`的代码实现
}
不过要注意,默认实现其实也是可以自定义逻辑的,只需要我们手动实现ne方法即可:
struct MyType;
impl PartialEq for MyType {
fn eq(&self, other: &MyType) -> bool {
// Custom implementation
}
fn ne(&self, other: &MyType) -> bool {
// Custom implementation
}
}
练习
这次的练习,是让我们为Ticket实现eq方法,以实现Ticket的==,!=操作,结合刚才所学到的内容

我们可以很轻松的编码:
impl PartialEq for Ticket {
fn eq(&self, other: &Ticket) -> bool {
self.title == other.title&& self.description == other.description&& self.status == other.status
}
}
让三个String字段都相等,即相等就好了。不得不说,Rust确实非常巧妙,尽管其他各种语言C/C++等,也都实现了运算符重载,但是我觉得Rust是做的最优雅的!
这一节的学习就到这里了
阅读剩余
版权声明:
作者:CN059
链接:https://www.cn059.com/2025/09/09/21%e3%80%81operator-overloading%ef%bc%88%e8%bf%90%e7%ae%97%e7%ac%a6%e9%87%8d%e8%bd%bd%ef%bc%89.html
文章版权归作者所有,未经允许请勿转载。
THE END
