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
