操作符的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 < otherEqual, // self == otherGreater, // 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的一个不足。
