当前位置:网站首页>【Rust 笔记】10-操作符重载
【Rust 笔记】10-操作符重载
2022-07-03 08:24:00 【phial03】
10 - 操作符重载
操作符重载:让自己定义的类型支持算术和其他操作。
支持操作符重载的特型:
类别 特型 操作符 一元操作符 std::ops::Neg
std::ops::Not
-x
!x
算术操作符 std::ops::Add
std::ops::Sub
std::ops::Mul
std::ops::Div
std::ops::Rem
x + y
x - y
x * y
x / y
x % y
位操作符 std::ops::BitAnd
std::ops::BitOr
std::ops::BitXor
std::ops::Shl
std::ops::Shr
x & y
x - y
x * y
x / y
x % y
复合赋值算术操作符 std::ops::AddAssign
std::ops::SubAssign
std::ops::MulAssign
std::ops::DivAssign
std::ops::RemAssign
x += y
x -= y
x *= y
x /= y
x %= y
复合赋值位操作符 std::ops::BitAndAssign
std::ops::BitOrAssign
std::ops::BitXorAssing
std::ops::ShlAssign
std::ops::ShrAssign
x &= y
`x比较 std::cmp::PartialEq
std::cmp::PartialOrd
x == y
、x != y
x < y
、x <= y
、x > y
、x >= y
索引 std::ops::Index
std::ops::IndexMut
x[y]
、&x[y]
x[y] = z
、&mut x[y]
10.1 - 算术与位操作符
10.1.1 - 一元操作符
*
引用操作符std::ops::Neg
特型:实现一元取反操作符-
。trait Neg { type Output; fn neg(self) -> Self::Output; }
std::ops::Not
特型:实现一元非操作符!
。trait Not { type Output; fn not(self) -> Self::Output; }
对复数值取反的泛型实现:
use std::ops::Neg; impl<T, O> Neg for Complex<T> where T: Neg<Output=O> { type Output = Complex<O>; fn neg(self) -> Complex<O> { Complex { re: -self.re; im: -self.im } } }
10.1.2 - 二元操作符
Rust 的所有数值类型都实现了算术操作符;
Rust 的整数类型和
bool
实现了位操作符。它们也实现了接受对这些类型的引用作为一个或两个操作数的逻辑。
算术操作符和位操作符的特型都有统一的形式:
// 针对^操作符的std::ops::BitXor的定义 trait BitXor<RHS=Self> { type Output; fn bitxor(self, rhs: RHS) -> Self::Output; }
使用
+
操作符可以将一个String
和一个&st
切片或另一个String
拼接起来。但是 Rust 不允许+
的左操作数是&str
,目的是阻止通过重复小的左操作数来构建长字符串。(会造成性能隐患:所需时间与最终字符串长度的平方成正相关)要一段一段的拼接字符串,最好使用
write!
。
10.1.3 - 复合赋值操作符
Rust 的所有数值类型都实现了算术复合赋值操作符;
Rust 的整数类型和
bool
还实现了位复合赋值操作符。对
Complex
类型进行AddAssign
的泛型实现:use std::ops::AddAssign; impl<T> AddAssign for Complex<T> where T: AddAssign<T> { fn add_assign(&mut self, rhs: Complex<T>) { self.re += rhs.re; self.im += rhs.im; } }
复合操作符的内置特型与对应的二元操作符的内置特型相互独立。
实现
std::ops::Add
不会自动实现std::ops::AddAssign
。如果要让自定义类型作为+=
操作符的左操作数,那么必须实现AddAssign
。与二元特型
Shl
和Shr
类似,ShlAssign
和ShrAssign
特型:没有将RHS
类型参数默认为Self
,所以实现时必须明确给出右操作数的类型。
10.2 - 相等测试
==
和!=
是对调用std::cmp::PartialEq
特型方法eq
和ne
的简写:assert_eq!(x == y, x.eq(&y)); assert_eq!(x != y, x.ne(&y));
std::cmp::PartialEq
的定义:trait PartialEq<Rhs: ?Sized = Self> { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } }
Complex
的完整实现:impl<T: PartialEq> PartialEq for Complex<T> { fn eq(&self, other: &Complex<T>) -> bool { self.re == other.re && self.im == other.im } }
Rhs: ?Sized
放宽了 Rust 对类型参数必须有大小的限制,以支持PartialEq<str>
或PartialEq<T>
这样的特型。方法eq
和ne
接收&Rhs
类型的参数,可以比较&str
和&[T]
。标准库将
Eq
定义为PartialEq
的扩展,且没有定义新方法:trait Eq: PartialEq<Self> { }
为
Complex
类型实现Eq
:impl<T: Eq> Eq for Complex<T> { }
在
Complex
类型定义的derive
属性中包含Eq
也可以实现:#[derive(Clone, Copy, Debug, Eq, PartialEq)] struct Complex<T> { ... }
10.3 - 顺序比较
Rust 通过特型 std::cmp::PartialOrd
规定了顺序比较操作符 <
、>
、<=
和 >=
的行为:
trait PartialOrd<Rhs = Self>: PartialEq<Rhs> where Rhs: ?Sized {
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
fn lt(&self, other: &Rhs) -> bool {
... }
fn le(&self, other: &Rhs) -> bool {
... }
fn gt(&self, other: &Rhs) -> bool {
... }
fn ge(&self, other: &Rhs) -> bool {
... }
}
10.4-Index 与 IndexMut
通过实现
std::ops::Index
和std::ops::IndexMut
特型,可以对相应类型使用类似a[i]
这样的索引表达式。trait Index<Idx> { type Output: ?Sized; fn index(&self, index: Idx) -> &Self::Output; } trait IndexMut<Idx>: Index<Idx> { fn index_mut(&mut self, index: Idx) -> &mut Self::Output; }
a[i..j]
是下述表达式的简写:*a.index(std::ops::Range { start: i, end: j })
10.5 - 其他操作符
*val
解引用操作符和.
调用方法的点操作符,可以使用 Deref
和 DerefMut
特型来重载。
下述操作符都不支持重载:
- 错误检查操作符
?
只能用于Result
值; - 逻辑操作符
&&
和||
仅限于布尔值; ..
操作符只能用于创建Range
值;&
操作符只能借用引用;=
操作符只能转移或复制值。f(x)
函数调用操作符不支持重载,如果要一个可调用的值,通常写一个闭包就可以了。
详见《Rust 程序设计》(吉姆 - 布兰迪、贾森 - 奥伦多夫著,李松峰译)第十二章
原文地址
边栏推荐
- 十六进制编码简介
- Creation and content of mapnode -- osgearth rendering engine series (2)
- Unity interactive water ripple post-treatment
- Unity notes 1
- 梯度下降法求解BP神经网络的简单Demo
- Osgearth north arrow display
- Simply start with the essence and principle of SOM neural network
- Unity change default editor
- Sequence of map implementation classes
- UE4 source code reading_ Bone model and animation system_ Animation node
猜你喜欢
Visual Studio (VS) shortcut keys
[cloud native] introduction and use of feign of microservices
数据库应用技术课程设计之商城管理系统
Unity change default editor
Cloudcompare learning (1) - cloudcompare compilation and common plug-in implementation
Display terrain database on osgearth ball
Base64编码简介
MAE
UE4 source code reading_ Bone model and animation system_ Animation process
Creation of osgearth earth files to the earth ------ osgearth rendering engine series (1)
随机推荐
Transmit pictures with Base64 encoding
Mall management system of database application technology course design
Unity editor expansion - window, sub window, menu, right-click menu (context menu)
[cloud native] introduction and use of feign of microservices
php-fpm软件的安装+openresty高速缓存搭建
Installation of PHP FPM software +openresty cache construction
Conversion between golang JSON format and structure
[updating] wechat applet learning notes_ three
C language - Introduction - essence Edition - take you into programming (I)
What is BFC?
Map的实现类的顺序性
Golang url的编码和解码
Explain sizeof, strlen, pointer, array and other combination questions in detail
UE4 call DLL
Delete the last character of the string in golang
Unity notes 1
Encoding and decoding of golang URL
Introduction to hexadecimal coding
Some understandings of 3dfiles
Huawei interview summary during the epidemic