Expand description
Overloadable operators.
Implementing these traits allows you to overload certain operators.
Some of these traits are imported by the prelude, so they are available inevery Rust program. Only operators backed by traits can be overloaded. Forexample, the addition operator (+) can be overloaded through theAddtrait, but since the assignment operator (=) has no backing trait, thereis no way of overloading its semantics. Additionally, this module does notprovide any mechanism to create new operators. If traitless overloading orcustom operators are required, you should look toward macros to extendRust’s syntax.
Implementations of operator traits should be unsurprising in theirrespective contexts, keeping in mind their usual meanings andoperator precedence. For example, when implementingMul, the operationshould have some resemblance to multiplication (and share expectedproperties like associativity).
Note that the&& and|| operators are currently not supported foroverloading. Due to their short circuiting nature, they require a differentdesign from traits for other operators likeBitAnd. Designs for them areunder discussion.
Many of the operators take their operands by value. In non-genericcontexts involving built-in types, this is usually not a problem.However, using these operators in generic code, requires someattention if values have to be reused as opposed to letting the operatorsconsume them. One option is to occasionally useclone.Another option is to rely on the types involved providing additionaloperator implementations for references. For example, for a user-definedtypeT which is supposed to support addition, it is probably a goodidea to have bothT and&T implement the traitsAdd<T> andAdd<&T> so that generic code can be written without unnecessarycloning.
§Examples
This example creates aPoint struct that implementsAdd andSub,and then demonstrates adding and subtracting twoPoints.
usestd::ops::{Add, Sub};#[derive(Debug, Copy, Clone, PartialEq)]structPoint { x: i32, y: i32,}implAddforPoint {typeOutput =Self;fnadd(self, other:Self) ->Self{Self{x:self.x + other.x, y:self.y + other.y} }}implSubforPoint {typeOutput =Self;fnsub(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});See the documentation for each trait for an example implementation.
TheFn,FnMut, andFnOnce traits are implemented by types that can beinvoked like functions. Note thatFn takes&self,FnMut takes&mut self andFnOnce takesself. These correspond to the three kinds ofmethods that can be invoked on an instance: call-by-reference,call-by-mutable-reference, and call-by-value. The most common use of thesetraits is to act as bounds to higher-level functions that take functions orclosures as arguments.
Taking aFn as a parameter:
fncall_with_one<F>(func: F) -> usizewhereF: Fn(usize) -> usize{ func(1)}letdouble = |x| x *2;assert_eq!(call_with_one(double),2);Taking aFnMut as a parameter:
fndo_twice<F>(mutfunc: F)whereF: FnMut(){ func(); func();}letmutx: usize =1;{letadd_two_to_x = || x +=2; do_twice(add_two_to_x);}assert_eq!(x,5);Taking aFnOnce as a parameter:
fnconsume_with_relish<F>(func: F)whereF: FnOnce() -> String{// `func` consumes its captured variables, so it cannot be run more // than onceprintln!("Consumed: {}", func());println!("Delicious!");// Attempting to invoke `func()` again will throw a `use of moved // value` error for `func`}letx = String::from("x");letconsume_and_return_x =move|| x;consume_with_relish(consume_and_return_x);// `consume_and_return_x` can no longer be invoked at this pointStructs§
- Range
- A (half-open) range bounded inclusively below and exclusively above(
start..end). - Range
From - A range only bounded inclusively below (
start..). - Range
Full - An unbounded range (
..). - Range
Inclusive - A range bounded inclusively below and above (
start..=end). - RangeTo
- A range only bounded exclusively above (
..end). - Range
ToInclusive - A range only bounded inclusively above (
..=end). - Yeet
Experimental - Implement
FromResidual<Yeet<T>>on your type to enabledo yeet exprsyntax in functions returning your type.
Enums§
- Bound
- An endpoint of a range of keys.
- Control
Flow - Used to tell an operation whether it should exit early or go on as usual.
- Coroutine
State Experimental - The result of a coroutine resumption.
- OneSided
Range Bound Experimental - An internal helper for
split_offfunctions indicatingwhich end aOneSidedRangeis bounded on.
Traits§
- Add
- The addition operator
+. - AddAssign
- The addition assignment operator
+=. - AsyncFn
- An async-aware version of the
Fntrait. - Async
FnMut - An async-aware version of the
FnMuttrait. - Async
FnOnce - An async-aware version of the
FnOncetrait. - BitAnd
- The bitwise AND operator
&. - BitAnd
Assign - The bitwise AND assignment operator
&=. - BitOr
- The bitwise OR operator
|. - BitOr
Assign - The bitwise OR assignment operator
|=. - BitXor
- The bitwise XOR operator
^. - BitXor
Assign - The bitwise XOR assignment operator
^=. - Deref
- Used for immutable dereferencing operations, like
*v. - Deref
Mut - Used for mutable dereferencing operations, like in
*v = 1;. - Div
- The division operator
/. - DivAssign
- The division assignment operator
/=. - Drop
- Custom code within the destructor.
- Fn
- The version of the call operator that takes an immutable receiver.
- FnMut
- The version of the call operator that takes a mutable receiver.
- FnOnce
- The version of the call operator that takes a by-value receiver.
- Index
- Used for indexing operations (
container[index]) in immutable contexts. - Index
Mut - Used for indexing operations (
container[index]) in mutable contexts. - Mul
- The multiplication operator
*. - MulAssign
- The multiplication assignment operator
*=. - Neg
- The unary negation operator
-. - Not
- The unary logical negation operator
!. - Range
Bounds RangeBoundsis implemented by Rust’s built-in range types, producedby range syntax like..,a..,..b,..=c,d..e, orf..=g.- Rem
- The remainder operator
%. - RemAssign
- The remainder assignment operator
%=. - Shl
- The left shift operator
<<. Note that because this trait is implementedfor all integer types with multiple right-hand-side types, Rust’s typechecker has special handling for_ << _, setting the result type forinteger operations to the type of the left-hand-side operand. This meansthat thougha << banda.shl(b)are one and the same from an evaluationstandpoint, they are different when it comes to type inference. - ShlAssign
- The left shift assignment operator
<<=. - Shr
- The right shift operator
>>. Note that because this trait is implementedfor all integer types with multiple right-hand-side types, Rust’s typechecker has special handling for_ >> _, setting the result type forinteger operations to the type of the left-hand-side operand. This meansthat thougha >> banda.shr(b)are one and the same from an evaluationstandpoint, they are different when it comes to type inference. - ShrAssign
- The right shift assignment operator
>>=. - Sub
- The subtraction operator
-. - SubAssign
- The subtraction assignment operator
-=. - Coerce
Shared Experimental - Allows reborrowable value to be reborrowed as shared, creating a copythat disables the source for writes for the lifetime of the copy.
- Coerce
Unsized Experimental - Trait that indicates that this is a pointer or a wrapper for one,where unsizing can be performed on the pointee.
- Coroutine
Experimental - The trait implemented by builtin coroutine types.
- Deref
Pure Experimental - Perma-unstable marker trait. Indicates that the type has a well-behaved
Deref(and, if applicable,DerefMut) implementation. This is relied on for soundnessof deref patterns. - Dispatch
From Dyn Experimental DispatchFromDynis used in the implementation of dyn-compatibility checks (specificallyallowing arbitrary self types), to guarantee that a method’s receiver type can be dispatched on.- From
Residual Experimental - Used to specify which residuals can be converted into which
crate::ops::Trytypes. - Into
Bounds Experimental - Used to convert a range into start and end bounds, consuming therange by value.
- OneSided
Range Experimental OneSidedRangeis implemented for built-in range types that are unboundedon one side. For example,a..,..band..=cimplementOneSidedRange,but..,d..e, andf..=gdo not.- Reborrow
Experimental - Allows value to be reborrowed as exclusive, creating a copy of the valuethat disables the source for reads and writes for the lifetime of the copy.
- Receiver
Experimental - Indicates that a struct can be used as a method receiver.That is, a type can use this type as a type of
self, like this: - Residual
Experimental - Allows retrieving the canonical type implementing
Trythat has this typeas its residual and allows it to hold anOas its output. - Try
Experimental - The
?operator andtry {}blocks.