3 > **<sup>Syntax</sup>**\
4 > _OperatorExpression_ :\
5 > [_BorrowExpression_]\
6 > | [_DereferenceExpression_]\
7 > | [_ErrorPropagationExpression_]\
8 > | [_NegationExpression_]\
9 > | [_ArithmeticOrLogicalExpression_]\
10 > | [_ComparisonExpression_]\
11 > | [_LazyBooleanExpression_]\
12 > | [_TypeCastExpression_]\
13 > | [_AssignmentExpression_]\
14 > | [_CompoundAssignmentExpression_]
16 Operators are defined for built in types by the Rust language. Many of the
17 following operators can also be overloaded using traits in `std::ops` or
22 Integer operators will panic when they overflow when compiled in debug mode.
23 The `-C debug-assertions` and `-C overflow-checks` compiler flags can be used
24 to control this more directly. The following things are considered to be
27 * When `+`, `*` or `-` create a value greater than the maximum value, or less
28 than the minimum value that can be stored. This includes unary `-` on the
29 smallest value of any signed integer type.
30 * Using `/` or `%`, where the left-hand argument is the smallest integer of a
31 signed integer type and the right-hand argument is `-1`.
32 * Using `<<` or `>>` where the right-hand argument is greater than or equal to
33 the number of bits in the type of the left-hand argument, or is negative.
37 > **<sup>Syntax</sup>**\
38 > _BorrowExpression_ :\
39 > (`&`|`&&`) [_Expression_]\
40 > | (`&`|`&&`) `mut` [_Expression_]
42 The `&` (shared borrow) and `&mut` (mutable borrow) operators are unary prefix
43 operators. When applied to a [place expression], this expressions produces a
44 reference (pointer) to the location that the value refers to. The memory
45 location is also placed into a borrowed state for the duration of the reference.
46 For a shared borrow (`&`), this implies that the place may not be mutated, but
47 it may be read or shared again. For a mutable borrow (`&mut`), the place may not
48 be accessed in any way until the borrow expires. `&mut` evaluates its operand in
49 a mutable place expression context. If the `&` or `&mut` operators are applied
50 to a [value expression], then a [temporary value] is created.
52 These operators cannot be overloaded.
56 // a temporary with value 7 is created that lasts for this scope.
57 let shared_reference = &7;
59 let mut array = [-2, 3, 9];
61 // Mutably borrows `array` for this scope.
62 // `array` may only be used through `mutable_reference`.
63 let mutable_reference = &mut array;
67 Even though `&&` is a single token ([the lazy 'and' operator](#lazy-boolean-operators)),
68 when used in the context of borrow expressions it works as two borrows:
78 let a = & & & & mut 10;
81 ## The dereference operator
83 > **<sup>Syntax</sup>**\
84 > _DereferenceExpression_ :\
85 > `*` [_Expression_]
87 The `*` (dereference) operator is also a unary prefix operator. When applied to
88 a [pointer](../types/pointer.md) it denotes the pointed-to location. If
89 the expression is of type `&mut T` and `*mut T`, and is either a local
90 variable, a (nested) field of a local variable or is a mutable [place
91 expression], then the resulting memory location can be assigned to.
92 Dereferencing a raw pointer requires `unsafe`.
94 On non-pointer types `*x` is equivalent to `*std::ops::Deref::deref(&x)` in an
95 [immutable place expression context](../expressions.md#mutability) and
96 `*std::ops::DerefMut::deref_mut(&mut x)` in a mutable place expression context.
106 ## The question mark operator
108 > **<sup>Syntax</sup>**\
109 > _ErrorPropagationExpression_ :\
110 > [_Expression_] `?`
112 The question mark operator (`?`) unwraps valid values or returns erroneous
113 values, propagating them to the calling function. It is a unary postfix
114 operator that can only be applied to the types `Result<T, E>` and `Option<T>`.
116 When applied to values of the `Result<T, E>` type, it propagates errors. If
117 the value is `Err(e)`, then it will return `Err(From::from(e))` from the
118 enclosing function or closure. If applied to `Ok(x)`, then it will unwrap the
119 value to evaluate to `x`.
122 # use std::num::ParseIntError;
123 fn try_to_parse() -> Result<i32, ParseIntError> {
124 let x: i32 = "123".parse()?; // x = 123
125 let y: i32 = "24a".parse()?; // returns an Err() immediately
126 Ok(x + y) // Doesn't run.
129 let res = try_to_parse();
130 println!("{:?}", res);
131 # assert!(res.is_err())
134 When applied to values of the `Option<T>` type, it propagates `None`s. If the
135 value is `None`, then it will return `None`. If applied to `Some(x)`, then it
136 will unwrap the value to evaluate to `x`.
139 fn try_option_some() -> Option<u8> {
143 assert_eq!(try_option_some(), Some(1));
145 fn try_option_none() -> Option<u8> {
149 assert_eq!(try_option_none(), None);
152 `?` cannot be overloaded.
154 ## Negation operators
156 > **<sup>Syntax</sup>**\
157 > _NegationExpression_ :\
158 > `-` [_Expression_]\
159 > | `!` [_Expression_]
161 These are the last two unary operators. This table summarizes the behavior of
162 them on primitive types and which traits are used to overload these operators
163 for other types. Remember that signed integers are always represented using
164 two's complement. The operands of all of these operators are evaluated in
165 [value expression context][value expression] so are moved or copied.
167 | Symbol | Integer | `bool` | Floating Point | Overloading Trait |
168 |--------|-------------|-------------|----------------|--------------------|
169 | `-` | Negation* | | Negation | `std::ops::Neg` |
170 | `!` | Bitwise NOT | Logical NOT | | `std::ops::Not` |
172 \* Only for signed integer types.
174 Here are some example of these operators
180 assert_eq!(true, !false);
183 ## Arithmetic and Logical Binary Operators
185 > **<sup>Syntax</sup>**\
186 > _ArithmeticOrLogicalExpression_ :\
187 > [_Expression_] `+` [_Expression_]\
188 > | [_Expression_] `-` [_Expression_]\
189 > | [_Expression_] `*` [_Expression_]\
190 > | [_Expression_] `/` [_Expression_]\
191 > | [_Expression_] `%` [_Expression_]\
192 > | [_Expression_] `&` [_Expression_]\
193 > | [_Expression_] `|` [_Expression_]\
194 > | [_Expression_] `^` [_Expression_]\
195 > | [_Expression_] `<<` [_Expression_]\
196 > | [_Expression_] `>>` [_Expression_]
198 Binary operators expressions are all written with infix notation. This table
199 summarizes the behavior of arithmetic and logical binary operators on
200 primitive types and which traits are used to overload these operators for other
201 types. Remember that signed integers are always represented using two's
202 complement. The operands of all of these operators are evaluated in [value
203 expression context][value expression] so are moved or copied.
205 | Symbol | Integer | `bool` | Floating Point | Overloading Trait |
206 |--------|-------------------------|-------------|----------------|--------------------|
207 | `+` | Addition | | Addition | `std::ops::Add` |
208 | `-` | Subtraction | | Subtraction | `std::ops::Sub` |
209 | `*` | Multiplication | | Multiplication | `std::ops::Mul` |
210 | `/` | Division* | | Division | `std::ops::Div` |
211 | `%` | Remainder | | Remainder | `std::ops::Rem` |
212 | `&` | Bitwise AND | Logical AND | | `std::ops::BitAnd` |
213 | <code>|</code> | Bitwise OR | Logical OR | | `std::ops::BitOr` |
214 | `^` | Bitwise XOR | Logical XOR | | `std::ops::BitXor` |
215 | `<<` | Left Shift | | | `std::ops::Shl` |
216 | `>>` | Right Shift** | | | `std::ops::Shr` |
218 \* Integer division rounds towards zero.
220 \*\* Arithmetic right shift on signed integer types, logical right shift on
221 unsigned integer types.
223 Here are examples of these operators being used.
226 assert_eq!(3 + 6, 9);
227 assert_eq!(5.5 - 1.25, 4.25);
228 assert_eq!(-5 * 14, -70);
229 assert_eq!(14 / 3, 4);
230 assert_eq!(100 % 7, 2);
231 assert_eq!(0b1010 & 0b1100, 0b1000);
232 assert_eq!(0b1010 | 0b1100, 0b1110);
233 assert_eq!(0b1010 ^ 0b1100, 0b110);
234 assert_eq!(13 << 3, 104);
235 assert_eq!(-10 >> 2, -3);
238 ## Comparison Operators
240 > **<sup>Syntax</sup>**\
241 > _ComparisonExpression_ :\
242 > [_Expression_] `==` [_Expression_]\
243 > | [_Expression_] `!=` [_Expression_]\
244 > | [_Expression_] `>` [_Expression_]\
245 > | [_Expression_] `<` [_Expression_]\
246 > | [_Expression_] `>=` [_Expression_]\
247 > | [_Expression_] `<=` [_Expression_]
249 Comparison operators are also defined both for primitive types and many type in
250 the standard library. Parentheses are required when chaining comparison
251 operators. For example, the expression `a == b == c` is invalid and may be
252 written as `(a == b) == c`.
254 Unlike arithmetic and logical operators, the traits for
255 overloading the operators the traits for these operators are used more
256 generally to show how a type may be compared and will likely be assumed to
257 define actual comparisons by functions that use these traits as bounds. Many
258 functions and macros in the standard library can then use that assumption
259 (although not to ensure safety). Unlike the arithmetic and logical operators
260 above, these operators implicitly take shared borrows of their operands,
261 evaluating them in [place expression context][place expression]:
268 ::std::cmp::PartialEq::eq(&a, &b);
271 This means that the operands don't have to be moved out of.
273 | Symbol | Meaning | Overloading method |
274 |--------|--------------------------|----------------------------|
275 | `==` | Equal | `std::cmp::PartialEq::eq` |
276 | `!=` | Not equal | `std::cmp::PartialEq::ne` |
277 | `>` | Greater than | `std::cmp::PartialOrd::gt` |
278 | `<` | Less than | `std::cmp::PartialOrd::lt` |
279 | `>=` | Greater than or equal to | `std::cmp::PartialOrd::ge` |
280 | `<=` | Less than or equal to | `std::cmp::PartialOrd::le` |
282 Here are examples of the comparison operators being used.
287 assert!(12.5 > 12.2);
288 assert!([1, 2, 3] < [1, 3, 4]);
290 assert!("World" >= "Hello");
293 ## Lazy boolean operators
295 > **<sup>Syntax</sup>**\
296 > _LazyBooleanExpression_ :\
297 > [_Expression_] `||` [_Expression_]\
298 > | [_Expression_] `&&` [_Expression_]
300 The operators `||` and `&&` may be applied to operands of boolean type. The
301 `||` operator denotes logical 'or', and the `&&` operator denotes logical
302 'and'. They differ from `|` and `&` in that the right-hand operand is only
303 evaluated when the left-hand operand does not already determine the result of
304 the expression. That is, `||` only evaluates its right-hand operand when the
305 left-hand operand evaluates to `false`, and `&&` only when it evaluates to
309 let x = false || true; // true
310 let y = false && panic!(); // false, doesn't evaluate `panic!()`
313 ## Type cast expressions
315 > **<sup>Syntax</sup>**\
316 > _TypeCastExpression_ :\
317 > [_Expression_] `as` [_TypeNoBounds_]
319 A type cast expression is denoted with the binary operator `as`.
321 Executing an `as` expression casts the value on the left-hand side to the type
322 on the right-hand side.
324 An example of an `as` expression:
327 # fn sum(values: &[f64]) -> f64 { 0.0 }
328 # fn len(values: &[f64]) -> i32 { 0 }
329 fn average(values: &[f64]) -> f64 {
330 let sum: f64 = sum(values);
331 let size: f64 = len(values) as f64;
336 `as` can be used to explicitly perform [coercions](../type-coercions.md), as
337 well as the following additional casts. Here `*T` means either `*const T` or
340 | Type of `e` | `U` | Cast performed by `e as U` |
341 |-----------------------|-----------------------|----------------------------------|
342 | Integer or Float type | Integer or Float type | Numeric cast |
343 | C-like enum | Integer type | Enum cast |
344 | `bool` or `char` | Integer type | Primitive to integer cast |
345 | `u8` | `char` | `u8` to `char` cast |
346 | `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast |
347 | `*T` where `T: Sized` | Numeric type | Pointer to address cast |
348 | Integer type | `*V` where `V: Sized` | Address to pointer cast |
349 | `&[T; n]` | `*const T` | Array to pointer cast |
350 | [Function pointer](../types/function-pointer.md) | `*V` where `V: Sized` | Function pointer to pointer cast |
351 | Function pointer | Integer | Function pointer to address cast |
352 | Closure \*\* | Function pointer | Closure to function pointer cast |
354 \* or `T` and `V` are compatible unsized types, e.g., both slices, both the
357 \*\* only for closures that do not capture (close over) any local variables
362 * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
363 * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
365 * Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
366 * zero-extend if the source is unsigned
367 * sign-extend if the source is signed
368 * Casting from a float to an integer will round the float towards zero
369 * **[NOTE: currently this will cause Undefined Behavior if the rounded
370 value cannot be represented by the target integer type][float-int]**.
371 This includes Inf and NaN. This is a bug and will be fixed.
372 * Casting from an integer to float will produce the closest possible float \*
373 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
374 * on overflow, infinity (of the same sign as the input) is produced
375 * note: with the current set of numeric types, overflow can only happen
376 on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)`
377 * Casting from an f32 to an f64 is perfect and lossless
378 * Casting from an f64 to an f32 will produce the closest possible f32 \*\*
379 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
380 * on overflow, infinity (of the same sign as the input) is produced
382 * Casts an enum to its discriminant, then uses a numeric cast if needed.
383 * Primitive to integer cast
384 * `false` casts to `0`, `true` casts to `1`
385 * `char` casts to the value of the code point, then uses a numeric cast if needed.
386 * `u8` to `char` cast
387 * Casts to the `char` with the corresponding code point.
389 \* if integer-to-float casts with this rounding mode and overflow behavior are
390 not supported natively by the hardware, these casts will likely be slower than
393 \*\* if f64-to-f32 casts with this rounding mode and overflow behavior are not
394 supported natively by the hardware, these casts will likely be slower than
397 \*\*\* as defined in IEEE 754-2008 §4.3.1: pick the nearest floating point
398 number, preferring the one with an even least significant digit if exactly
399 halfway between two floating point numbers.
401 [float-int]: https://github.com/rust-lang/rust/issues/10184
403 ## Assignment expressions
405 > **<sup>Syntax</sup>**\
406 > _AssignmentExpression_ :\
407 > [_Expression_] `=` [_Expression_]
409 An _assignment expression_ consists of a [place expression] followed by an
410 equals sign (`=`) and a [value expression]. Such an expression always has
413 Evaluating an assignment expression [drops](../destructors.md) the left-hand
414 operand, unless it's an uninitialized local variable or field of a local variable,
415 and [either copies or moves](../expressions.md#moved-and-copied-types) its
416 right-hand operand to its left-hand operand. The left-hand operand must be a
417 place expression: using a value expression results in a compiler error, rather
418 than promoting it to a temporary.
426 ## Compound assignment expressions
428 > **<sup>Syntax</sup>**\
429 > _CompoundAssignmentExpression_ :\
430 > [_Expression_] `+=` [_Expression_]\
431 > | [_Expression_] `-=` [_Expression_]\
432 > | [_Expression_] `*=` [_Expression_]\
433 > | [_Expression_] `/=` [_Expression_]\
434 > | [_Expression_] `%=` [_Expression_]\
435 > | [_Expression_] `&=` [_Expression_]\
436 > | [_Expression_] `|=` [_Expression_]\
437 > | [_Expression_] `^=` [_Expression_]\
438 > | [_Expression_] `<<=` [_Expression_]\
439 > | [_Expression_] `>>=` [_Expression_]
441 The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be
442 composed with the `=` operator. The expression `place_exp OP= value` is
443 equivalent to `place_expr = place_expr OP val`. For example, `x = x + 1` may be
444 written as `x += 1`. Any such expression always has the [`unit` type].
445 These operators can all be overloaded using the trait with the same name as for
446 the normal operation followed by 'Assign', for example, `std::ops::AddAssign`
447 is used to overload `+=`. As with `=`, `place_expr` must be a [place
456 [place expression]: ../expressions.md#place-expressions-and-value-expressions
457 [value expression]: ../expressions.md#place-expressions-and-value-expressions
458 [temporary value]: ../expressions.md#temporary-lifetimes
459 [float-int]: https://github.com/rust-lang/rust/issues/10184
460 [float-float]: https://github.com/rust-lang/rust/issues/15536
461 [`unit` type]: ../types/tuple.md
463 [_BorrowExpression_]: #borrow-operators
464 [_DereferenceExpression_]: #the-dereference-operator
465 [_ErrorPropagationExpression_]: #the-question-mark-operator
466 [_NegationExpression_]: #negation-operators
467 [_ArithmeticOrLogicalExpression_]: #arithmetic-and-logical-binary-operators
468 [_ComparisonExpression_]: #comparison-operators
469 [_LazyBooleanExpression_]: #lazy-boolean-operators
470 [_TypeCastExpression_]: #type-cast-expressions
471 [_AssignmentExpression_]: #assignment-expressions
472 [_CompoundAssignmentExpression_]: #compound-assignment-expressions
474 [_Expression_]: ../expressions.md
475 [_TypeNoBounds_]: ../types.md#type-expressions