操作符的trait
Category | Trait | Operator |
---|---|---|
Unary operators | std::ops::Neg | -x |
std::ops::Not | !x | |
Arithmetic operators | std::ops::Add | x + y |
std::ops::Sub | x - y | |
std::ops::Mul | x * y | |
std::ops::Div | x / y | |
std::ops::Rem | x % y | |
Bitwise operators | std::ops::BitAnd | x & y |
std::ops::BitOr | x | y | |
std::ops::BitXor | x ^ y | |
std::ops::Shl | x << y | |
std::ops::Shr | x >> y | |
Compound assignment arithmetic operators |
std::ops::AddAssign | x += y |
std::ops::SubAssign | x -= y | |
std::ops::MulAssign | x *= y | |
std::ops::DivAssign | x /= y | |
std::ops::RemAssign | x %= y | |
Compound assignment bitwise operators |
std::ops::BitAndAssign | x &= y |
std::ops::BitOrAssign | x |= y | |
std::ops::BitXorAssign | x ^= y | |
std::ops::ShlAssign | x <<= y | |
std::ops::ShrAssign | x >>= y | |
Comparison | std::cmp::PartialEq | x == y, x != y |
std::cmp::PartialOrd | x < y, x <= y, x > y, x >= y | |
Indexing | std::ops::Index | x[y], &x[y] |
std::ops::IndexMut | x[y] = z, &mut x[y] |
运算和比较
+
操作符可以用来将String
和String
或&str
拼接到一起,但不允许&str
作为+
的左操作数,因为讲多个&str
拼接到一起性能极差。
运算操作符会取变量的值,而比较操作符是取引用。
相等比较为什么是PartialEq,因为在数学里,相等要满足3个条件:
- 如果x == y那y == x也要成立,交换性。
- 如果x == y且y == z,那x == z也要成立, 传递性。
- x == x必须成立。
因为Rust的浮点数是按照IEEE标准实现的,而IEEE标准要求必须有一个NaN
值,而这个NaN
值必须和任何值都不相等,包括自己。所以rust只满足前两个条件,所以是PartialEq。但还有另外一个traitEq
是完全满足以上条件的,rust的数字类型初浮点数意外都实现了Eq
。而且Eq
是PartialEq
的subtrait。
PartialOrd
是PartialEq
的subtrait,能比较大小的值也必须能判断相等。PartialOrd
必须实现的方法是partial_cmp
,partial_cmp
返回一个Option<Ordering>
enum Ordering {
Less, // self < other
Equal, // self == other
Greater, // self > other
}
如果Option
的值是None
,说明两个值不能比较大小,也不相等,是无序的。在Rust的所有基础类型中,只有浮点数有可能返回None
,也就是比较NaN
的时候。
和相等一样也有一个Ord trait,实现了这个trait的类型不会返回Option而是直接返回Ordering,认为比较永远会有结果。和相等一样也是出了浮点数都实现了Ord。
索引操作符
索引操作符由两个trait实现:std::ops::Index
和std::ops::IndexMut
,他们需要实现的方法分别是index
和index_mut
。
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;
}
索引的类型是泛型,因为可以想普通数组取单个元素那样用usize做索引,也可以像取slice那样用Range做索引。HashMap用hashable做索引,BTreeMap用Ordered做索引。
map类没有实现IndexMut,所以m["十"] = 10
的直接赋值是不能的。因为index_mut返回的是一个引用,想要有引用就必须先有一个值,所以就得先初始化一个值,但赋值操作马上就赋了一个新值,那刚初始化的那个值又要被丢弃,这样的操作太浪费。这也是IndexMut的一个不足。