rust支持很多运算符,大致可以分为如下几类:
- 赋值运算符
- 比较运算符
- 算术运算符
- 解引用运算符
这里不介绍运算符的作用,而是介绍rust中运算符的重载。rust中的重载依靠trait完成。
赋值运算符
=
等于,在rusht中语义中默认是move的。move指的是所有权的转移。
比较运算符
==、!=、>、<、<=、>=。
==、!=运算符的重载依靠于std::cmp模块下的PartialEq和Eq。
PartialEq(部分相等)
需要实现的方法
eq
fn eq(&self, other: &Rhs) -> bool
其中Rhs为一个泛型。
注:泛型是一些类型的集合,它通常和trait一起使用,通过trait来作为条件约束泛型。
实例:
struct Point {
order: u32,
x: i32,
y: i32,
}
impl PartialEq<u32> for Point {
fn eq(&self, other: &u32) -> bool {
self.order == *other
}
}
fn main() {
let one = Point {
order: 1,
x: 2,
y: 3,
};
println!("{:?}", one == 2);
}
自动实现的方法
ne
Eq
一个标记trait,它的实现需要PartiaEq先实现,全等。
能体现这两种区别的是:浮点数之中特别数NAN, NAN和NAN不相等。
Ord
需要实现的方法
cmp
fn cmp(&self, other: &Self) -> Ordering
自动实现的方法
max
min
PartialOrd
需要实现的方法
partial_cmp
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>
在这个函数中Rhs为泛型,返回值为Option
注意:当此函数表示返回None,表示无法比较。
Ordering的定义如下
pub enum Ordering {
Less, //小于
Equal,//等于
Greater,//大于
}
自动实现的方法
lt
le
gt
ge
算术运算符
除了比较运算符的trait处在std::cmp模块下,大多数运算符的重载位于std::ops模块。这里只介绍常用运算符的重载。
加法重载
加法运算依靠Add trait实现,其主要实现的方法如下:
fn add(self, rhs: Rhs) -> Self::Output
在这个方法中,Rhs为一个泛型。需要注意的是Self::Output。这是trait的一种写法,叫做关联类型,它同样是泛型的一种限定,在实现此trait之前,我们必须指定它的关联类型,不是一种泛型,而是具体的类型。
具体实例如下:
use std::ops::Add;
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
impl Add for Point {
type Output = Self;
fn add(self, other: Self) -> Point {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
fn main() {
let x = Point { x: 1, y: 1 };
let y = Point { x: 2, y: 4 };
let z = x + y;
println!("{:?}", z);
}
我们还可以实现这个例子的泛型版本,具体可以看官网的例子。减法等其他算术运算符的和加法类型。
解引用
解引用实现于Deref和DerefMut trait。这个trait的运用,可以方便使用指针类型后的值。其中DerefMut只用于智能指针的使用。
Deref需要实现的方法如下:
fn deref(&self) -> &Self::Target
注意:如果T实现了Deref