1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
//! 可重载的运算符。
//!
//! 实现这些 traits 可使您重载某些运算符。
//!
//! 其中的某些 traits 由 prelude 导入,因此在每个 Rust 程序中都可用。只能重载由 traits 支持的运算符。
//! 例如,可以通过 [`Add`] trait 重载加法运算符 (`+`),但是由于赋值运算符 (`=`) 没有后备 trait,因此无法重载其语义。
//! 此外,此模块不提供任何机制来创建新的运算符。
//! 如果需要无特征重载或自定义运算符,则应使用宏或编译器插件来扩展 Rust 的语法。
//!
//! 考虑到它们的通常含义和 [运算符优先级][operator precedence],运算符 traits 的实现在它们各自的上下文中应该不足为奇。
//! 例如,当实现 [`Mul`] 时,该操作应与乘法有些相似 (并共享期望的属性,如关联性)。
//!
//! 请注意,目前不支持重载 `&&` 和 `||` 运算符。由于它们的短路特性,它们需要与 traits 不同的设计用于其他运算符,如 [`BitAnd`]。他们的设计正在讨论中。
//!
//! 许多运算符都按值取其操作数。在涉及内置类型的非泛型上下文中,这通常不是问题。
//! 但是,如果必须重用值,而不是让运算符使用它们,那么在泛型代码中使用这些运算符就需要引起注意。一种选择是偶尔使用 [`clone`]。
//! 另一个选择是依靠所涉及的类型,为引用提供其他运算符实现。
//! 例如,对于应该支持加法的用户定义类型 `T`,将 `T` 和 `&T` 都实现 traits [`Add<T>`][`Add`] 和 [`Add<&T>`][`Add`] 可能是一个好主意,这样就可以编写泛型代码而不必进行不必要的克隆。
//!
//!
//! # Examples
//!
//! 本示例创建一个实现 [`Add`] 和 [`Sub`] 的 `Point` 结构体,然后演示加减两个 Point。
//!
//! ```rust
//! use std::ops::{Add, Sub};
//!
//! #[derive(Debug, Copy, Clone, PartialEq)]
//! struct Point {
//! x: i32,
//! y: i32,
//! }
//!
//! impl Add for Point {
//! type Output = Self;
//!
//! fn add(self, other: Self) -> Self {
//! Self {x: self.x + other.x, y: self.y + other.y}
//! }
//! }
//!
//! impl Sub for Point {
//! type Output = Self;
//!
//! fn sub(self, other: Self) -> Self {
//! Self {x: self.x - other.x, y: self.y - other.y}
//! }
//! }
//!
//! assert_eq!(Point {x: 3, y: 3}, Point {x: 1, y: 0} + Point {x: 2, y: 3});
//! assert_eq!(Point {x: -1, y: -3}, Point {x: 1, y: 0} - Point {x: 2, y: 3});
//! ```
//!
//! 有关示例实现,请参见每个 trait 的文档。
//!
//! [`Fn`],[`FnMut`] 和 [`FnOnce`] traits 由可以像函数一样调用的类型实现。请注意,[`Fn`] 占用 `&self`,[`FnMut`] 占用 `&mut self`,[`FnOnce`] 占用 `self`。
//! 这些对应于可以在实例上调用的三种方法:引用调用、可变引用调用和值调用。
//! 这些 traits 的最常见用法是充当以函数或闭包为参数的高级函数的界限。
//!
//! 以 [`Fn`] 作为参数:
//!
//! ```rust
//! fn call_with_one<F>(func: F) -> usize
//! where F: Fn(usize) -> usize
//! {
//! func(1)
//! }
//!
//! let double = |x| x * 2;
//! assert_eq!(call_with_one(double), 2);
//! ```
//!
//! 以 [`FnMut`] 作为参数:
//!
//! ```rust
//! fn do_twice<F>(mut func: F)
//! where F: FnMut()
//! {
//! func();
//! func();
//! }
//!
//! let mut x: usize = 1;
//! {
//! let add_two_to_x = || x += 2;
//! do_twice(add_two_to_x);
//! }
//!
//! assert_eq!(x, 5);
//! ```
//!
//! 以 [`FnOnce`] 作为参数:
//!
//! ```rust
//! fn consume_with_relish<F>(func: F)
//! where F: FnOnce() -> String
//! {
//! // `func` 消耗其捕获的变量,因此不能多次运行
//! //
//! println!("Consumed: {}", func());
//!
//! println!("Delicious!");
//!
//! // 再次尝试调用 `func()` 将为 `func` 引发 `use of moved value` 错误
//! //
//! }
//!
//! let x = String::from("x");
//! let consume_and_return_x = move || x;
//! consume_with_relish(consume_and_return_x);
//!
//! // 此时无法再调用 `consume_and_return_x`
//! ```
//!
//! [`clone`]: Clone::clone
//! [operator precedence]: ../../reference/expressions.html#expression-precedence
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
#![stable(feature = "rust1", since = "1.0.0")]
mod arith;
mod bit;
mod control_flow;
mod deref;
mod drop;
mod function;
mod generator;
mod index;
mod index_range;
mod range;
mod try_trait;
mod unsize;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
#[stable(feature = "op_assign_traits", since = "1.8.0")]
pub use self::arith::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
#[stable(feature = "op_assign_traits", since = "1.8.0")]
pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::deref::{Deref, DerefMut};
#[unstable(feature = "receiver_trait", issue = "none")]
pub use self::deref::Receiver;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::drop::Drop;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::function::{Fn, FnMut, FnOnce};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::index::{Index, IndexMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
pub(crate) use self::index_range::IndexRange;
#[stable(feature = "inclusive_range", since = "1.26.0")]
pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
#[unstable(feature = "one_sided_range", issue = "69780")]
pub use self::range::OneSidedRange;
#[unstable(feature = "try_trait_v2", issue = "84277")]
pub use self::try_trait::{FromResidual, Try};
#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
pub use self::try_trait::Yeet;
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
pub use self::try_trait::Residual;
pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
#[unstable(feature = "generator_trait", issue = "43122")]
pub use self::generator::{Generator, GeneratorState};
#[unstable(feature = "coerce_unsized", issue = "18598")]
pub use self::unsize::CoerceUnsized;
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
pub use self::unsize::DispatchFromDyn;
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
pub use self::control_flow::ControlFlow;