]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/expressions/operator-expr.md
New upstream version 1.51.0+dfsg1
[rustc.git] / src / doc / reference / src / expressions / operator-expr.md
1 # Operator expressions
2
3 > **<sup>Syntax</sup>**\
4 > _OperatorExpression_ :\
5 > &nbsp;&nbsp; &nbsp;&nbsp; [_BorrowExpression_]\
6 > &nbsp;&nbsp; | [_DereferenceExpression_]\
7 > &nbsp;&nbsp; | [_ErrorPropagationExpression_]\
8 > &nbsp;&nbsp; | [_NegationExpression_]\
9 > &nbsp;&nbsp; | [_ArithmeticOrLogicalExpression_]\
10 > &nbsp;&nbsp; | [_ComparisonExpression_]\
11 > &nbsp;&nbsp; | [_LazyBooleanExpression_]\
12 > &nbsp;&nbsp; | [_TypeCastExpression_]\
13 > &nbsp;&nbsp; | [_AssignmentExpression_]\
14 > &nbsp;&nbsp; | [_CompoundAssignmentExpression_]
15
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
18 `std::cmp`.
19
20 ## Overflow
21
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
25 overflow:
26
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.
34
35 ## Borrow operators
36
37 > **<sup>Syntax</sup>**\
38 > _BorrowExpression_ :\
39 > &nbsp;&nbsp; &nbsp;&nbsp; (`&`|`&&`) [_Expression_]\
40 > &nbsp;&nbsp; | (`&`|`&&`) `mut` [_Expression_]
41
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.
51
52 These operators cannot be overloaded.
53
54 ```rust
55 {
56 // a temporary with value 7 is created that lasts for this scope.
57 let shared_reference = &7;
58 }
59 let mut array = [-2, 3, 9];
60 {
61 // Mutably borrows `array` for this scope.
62 // `array` may only be used through `mutable_reference`.
63 let mutable_reference = &mut array;
64 }
65 ```
66
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:
69
70 ```rust
71 // same meanings:
72 let a = && 10;
73 let a = & & 10;
74
75 // same meanings:
76 let a = &&&& mut 10;
77 let a = && && mut 10;
78 let a = & & & & mut 10;
79 ```
80
81 ## The dereference operator
82
83 > **<sup>Syntax</sup>**\
84 > _DereferenceExpression_ :\
85 > &nbsp;&nbsp; `*` [_Expression_]
86
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` or `*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`.
93
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.
97
98 ```rust
99 let x = &7;
100 assert_eq!(*x, 7);
101 let y = &mut 9;
102 *y = 11;
103 assert_eq!(*y, 11);
104 ```
105
106 ## The question mark operator
107
108 > **<sup>Syntax</sup>**\
109 > _ErrorPropagationExpression_ :\
110 > &nbsp;&nbsp; [_Expression_] `?`
111
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>`.
115
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`.
120
121 ```rust
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.
127 }
128
129 let res = try_to_parse();
130 println!("{:?}", res);
131 # assert!(res.is_err())
132 ```
133
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`.
137
138 ```rust
139 fn try_option_some() -> Option<u8> {
140 let val = Some(1)?;
141 Some(val)
142 }
143 assert_eq!(try_option_some(), Some(1));
144
145 fn try_option_none() -> Option<u8> {
146 let val = None?;
147 Some(val)
148 }
149 assert_eq!(try_option_none(), None);
150 ```
151
152 `?` cannot be overloaded.
153
154 ## Negation operators
155
156 > **<sup>Syntax</sup>**\
157 > _NegationExpression_ :\
158 > &nbsp;&nbsp; &nbsp;&nbsp; `-` [_Expression_]\
159 > &nbsp;&nbsp; | `!` [_Expression_]
160
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.
166
167 | Symbol | Integer | `bool` | Floating Point | Overloading Trait |
168 |--------|-------------|-------------|----------------|--------------------|
169 | `-` | Negation* | | Negation | `std::ops::Neg` |
170 | `!` | Bitwise NOT | Logical NOT | | `std::ops::Not` |
171
172 \* Only for signed integer types.
173
174 Here are some example of these operators
175
176 ```rust
177 let x = 6;
178 assert_eq!(-x, -6);
179 assert_eq!(!x, -7);
180 assert_eq!(true, !false);
181 ```
182
183 ## Arithmetic and Logical Binary Operators
184
185 > **<sup>Syntax</sup>**\
186 > _ArithmeticOrLogicalExpression_ :\
187 > &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `+` [_Expression_]\
188 > &nbsp;&nbsp; | [_Expression_] `-` [_Expression_]\
189 > &nbsp;&nbsp; | [_Expression_] `*` [_Expression_]\
190 > &nbsp;&nbsp; | [_Expression_] `/` [_Expression_]\
191 > &nbsp;&nbsp; | [_Expression_] `%` [_Expression_]\
192 > &nbsp;&nbsp; | [_Expression_] `&` [_Expression_]\
193 > &nbsp;&nbsp; | [_Expression_] `|` [_Expression_]\
194 > &nbsp;&nbsp; | [_Expression_] `^` [_Expression_]\
195 > &nbsp;&nbsp; | [_Expression_] `<<` [_Expression_]\
196 > &nbsp;&nbsp; | [_Expression_] `>>` [_Expression_]
197
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.
204
205 | Symbol | Integer | `bool` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait |
206 |--------|-------------------------|-------------|----------------|--------------------| ------------------------------------- |
207 | `+` | Addition | | Addition | `std::ops::Add` | `std::ops::AddAssign` |
208 | `-` | Subtraction | | Subtraction | `std::ops::Sub` | `std::ops::SubAssign` |
209 | `*` | Multiplication | | Multiplication | `std::ops::Mul` | `std::ops::MulAssign` |
210 | `/` | Division* | | Division | `std::ops::Div` | `std::ops::DivAssign` |
211 | `%` | Remainder | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` |
212 | `&` | Bitwise AND | Logical AND | | `std::ops::BitAnd` | `std::ops::BitAndAssign` |
213 | <code>&#124;</code> | Bitwise OR | Logical OR | | `std::ops::BitOr` | `std::ops::BitOrAssign` |
214 | `^` | Bitwise XOR | Logical XOR | | `std::ops::BitXor` | `std::ops::BitXorAssign` |
215 | `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` |
216 | `>>` | Right Shift** | | | `std::ops::Shr` | `std::ops::ShrAssign` |
217
218 \* Integer division rounds towards zero.
219
220 \*\* Arithmetic right shift on signed integer types, logical right shift on
221 unsigned integer types.
222
223 Here are examples of these operators being used.
224
225 ```rust
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);
236 ```
237
238 ## Comparison Operators
239
240 > **<sup>Syntax</sup>**\
241 > _ComparisonExpression_ :\
242 > &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `==` [_Expression_]\
243 > &nbsp;&nbsp; | [_Expression_] `!=` [_Expression_]\
244 > &nbsp;&nbsp; | [_Expression_] `>` [_Expression_]\
245 > &nbsp;&nbsp; | [_Expression_] `<` [_Expression_]\
246 > &nbsp;&nbsp; | [_Expression_] `>=` [_Expression_]\
247 > &nbsp;&nbsp; | [_Expression_] `<=` [_Expression_]
248
249 Comparison operators are also defined both for primitive types and many types
250 in 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`.
253
254 Unlike arithmetic and logical operators, the traits for overloading these
255 operators are used more generally to show how a type may be compared and will
256 likely be assumed to define actual comparisons by functions that use these
257 traits as bounds. Many functions and macros in the standard library can then
258 use that assumption (although not to ensure safety). Unlike the arithmetic
259 and logical operators above, these operators implicitly take shared borrows
260 of their operands, evaluating them in [place expression context][place expression]:
261
262 ```rust
263 # let a = 1;
264 # let b = 1;
265 a == b;
266 // is equivalent to
267 ::std::cmp::PartialEq::eq(&a, &b);
268 ```
269
270 This means that the operands don't have to be moved out of.
271
272 | Symbol | Meaning | Overloading method |
273 |--------|--------------------------|----------------------------|
274 | `==` | Equal | `std::cmp::PartialEq::eq` |
275 | `!=` | Not equal | `std::cmp::PartialEq::ne` |
276 | `>` | Greater than | `std::cmp::PartialOrd::gt` |
277 | `<` | Less than | `std::cmp::PartialOrd::lt` |
278 | `>=` | Greater than or equal to | `std::cmp::PartialOrd::ge` |
279 | `<=` | Less than or equal to | `std::cmp::PartialOrd::le` |
280
281 Here are examples of the comparison operators being used.
282
283 ```rust
284 assert!(123 == 123);
285 assert!(23 != -12);
286 assert!(12.5 > 12.2);
287 assert!([1, 2, 3] < [1, 3, 4]);
288 assert!('A' <= 'B');
289 assert!("World" >= "Hello");
290 ```
291
292 ## Lazy boolean operators
293
294 > **<sup>Syntax</sup>**\
295 > _LazyBooleanExpression_ :\
296 > &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `||` [_Expression_]\
297 > &nbsp;&nbsp; | [_Expression_] `&&` [_Expression_]
298
299 The operators `||` and `&&` may be applied to operands of boolean type. The
300 `||` operator denotes logical 'or', and the `&&` operator denotes logical
301 'and'. They differ from `|` and `&` in that the right-hand operand is only
302 evaluated when the left-hand operand does not already determine the result of
303 the expression. That is, `||` only evaluates its right-hand operand when the
304 left-hand operand evaluates to `false`, and `&&` only when it evaluates to
305 `true`.
306
307 ```rust
308 let x = false || true; // true
309 let y = false && panic!(); // false, doesn't evaluate `panic!()`
310 ```
311
312 ## Type cast expressions
313
314 > **<sup>Syntax</sup>**\
315 > _TypeCastExpression_ :\
316 > &nbsp;&nbsp; [_Expression_] `as` [_TypeNoBounds_]
317
318 A type cast expression is denoted with the binary operator `as`.
319
320 Executing an `as` expression casts the value on the left-hand side to the type
321 on the right-hand side.
322
323 An example of an `as` expression:
324
325 ```rust
326 # fn sum(values: &[f64]) -> f64 { 0.0 }
327 # fn len(values: &[f64]) -> i32 { 0 }
328 fn average(values: &[f64]) -> f64 {
329 let sum: f64 = sum(values);
330 let size: f64 = len(values) as f64;
331 sum / size
332 }
333 ```
334
335 `as` can be used to explicitly perform [coercions](../type-coercions.md), as
336 well as the following additional casts. Here `*T` means either `*const T` or
337 `*mut T`.
338
339 | Type of `e` | `U` | Cast performed by `e as U` |
340 |-----------------------|-----------------------|----------------------------------|
341 | Integer or Float type | Integer or Float type | Numeric cast |
342 | C-like enum | Integer type | Enum cast |
343 | `bool` or `char` | Integer type | Primitive to integer cast |
344 | `u8` | `char` | `u8` to `char` cast |
345 | `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast |
346 | `*T` where `T: Sized` | Numeric type | Pointer to address cast |
347 | Integer type | `*V` where `V: Sized` | Address to pointer cast |
348 | `&[T; n]` | `*const T` | Array to pointer cast |
349 | [Function item] | [Function pointer] | Function item to function pointer cast |
350 | [Function item] | `*V` where `V: Sized` | Function item to pointer cast |
351 | [Function item] | Integer | Function item to address cast |
352 | [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast |
353 | [Function pointer] | Integer | Function pointer to address cast |
354 | Closure \*\* | Function pointer | Closure to function pointer cast |
355
356 \* or `T` and `V` are compatible unsized types, e.g., both slices, both the
357 same trait object.
358
359 \*\* only for closures that do not capture (close over) any local variables
360
361 ### Semantics
362
363 * Numeric cast
364 * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
365 * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
366 truncate
367 * Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
368 * zero-extend if the source is unsigned
369 * sign-extend if the source is signed
370 * Casting from a float to an integer will round the float towards zero
371 * `NaN` will return `0`
372 * Values larger than the maximum integer value will saturate to the
373 maximum value of the integer type.
374 * Values smaller than the minimum integer value will saturate to the
375 minimum value of the integer type.
376 * Casting from an integer to float will produce the closest possible float \*
377 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
378 * on overflow, infinity (of the same sign as the input) is produced
379 * note: with the current set of numeric types, overflow can only happen
380 on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)`
381 * Casting from an f32 to an f64 is perfect and lossless
382 * Casting from an f64 to an f32 will produce the closest possible f32 \*\*
383 * if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
384 * on overflow, infinity (of the same sign as the input) is produced
385 * Enum cast
386 * Casts an enum to its discriminant, then uses a numeric cast if needed.
387 * Primitive to integer cast
388 * `false` casts to `0`, `true` casts to `1`
389 * `char` casts to the value of the code point, then uses a numeric cast if needed.
390 * `u8` to `char` cast
391 * Casts to the `char` with the corresponding code point.
392
393 \* if integer-to-float casts with this rounding mode and overflow behavior are
394 not supported natively by the hardware, these casts will likely be slower than
395 expected.
396
397 \*\* if f64-to-f32 casts with this rounding mode and overflow behavior are not
398 supported natively by the hardware, these casts will likely be slower than
399 expected.
400
401 \*\*\* as defined in IEEE 754-2008 &sect;4.3.1: pick the nearest floating point
402 number, preferring the one with an even least significant digit if exactly
403 halfway between two floating point numbers.
404
405 ## Assignment expressions
406
407 > **<sup>Syntax</sup>**\
408 > _AssignmentExpression_ :\
409 > &nbsp;&nbsp; [_Expression_] `=` [_Expression_]
410
411 An *assignment expression* moves a value into a specified place.
412
413 An assignment expression consists of a [mutable] [place expression], the
414 *assigned place operand*, followed by an equals sign (`=`) and a [value
415 expression], the *assigned value operand*.
416
417 Unlike other place operands, the assigned place operand must be a place
418 expression. Attempting to use a value expression is a compiler error rather
419 than promoting it to a temporary.
420
421 Evaluating assignment expressions begins by evaluating its operands. The
422 assigned value operand is evaluated first, followed by the assigned place
423 operand.
424
425 > **Note**: This is different than other expressions in that the right operand
426 > is evaluated before the left one.
427
428 It then has the effect of first [dropping] the value at the assigned place,
429 unless the place is an uninitialized local variable or an uninitialized field of
430 a local variable. Next it either [copies or moves] the assigned value to the
431 assigned place.
432
433 An assignment expression always produces [the unit value][unit].
434
435 Example:
436
437 ```rust
438 let mut x = 0;
439 let y = 0;
440 x = y;
441 ```
442
443 ## Compound assignment expressions
444
445 > **<sup>Syntax</sup>**\
446 > _CompoundAssignmentExpression_ :\
447 > &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] `+=` [_Expression_]\
448 > &nbsp;&nbsp; | [_Expression_] `-=` [_Expression_]\
449 > &nbsp;&nbsp; | [_Expression_] `*=` [_Expression_]\
450 > &nbsp;&nbsp; | [_Expression_] `/=` [_Expression_]\
451 > &nbsp;&nbsp; | [_Expression_] `%=` [_Expression_]\
452 > &nbsp;&nbsp; | [_Expression_] `&=` [_Expression_]\
453 > &nbsp;&nbsp; | [_Expression_] `|=` [_Expression_]\
454 > &nbsp;&nbsp; | [_Expression_] `^=` [_Expression_]\
455 > &nbsp;&nbsp; | [_Expression_] `<<=` [_Expression_]\
456 > &nbsp;&nbsp; | [_Expression_] `>>=` [_Expression_]
457
458 *Compound assignment expressions* combine arithmetic and logical binary
459 operators with assignment expressions.
460
461 For example:
462
463 ```rust
464 let mut x = 5;
465 x += 1;
466 assert!(x == 6);
467 ```
468
469 The syntax of compound assignment is a [mutable] [place expression], the
470 *assigned operand*, then one of the operators followed by an `=` as a single
471 token (no whitespace), and then a [value expression], the *modifying operand*.
472
473 Unlike other place operands, the assigned place operand must be a place
474 expression. Attempting to use a value expression is a compiler error rather
475 than promoting it to a temporary.
476
477 Evaluation of compound assignment expressions depends on the types of the
478 operators.
479
480 If both types are primitives, then the modifying operand will be evaluated
481 first followed by the assigned operand. It will then set the value of the
482 assigned operand's place to the value of performing the operation of the
483 operator with the values of the assigned operand and modifying operand.
484
485 > **Note**: This is different than other expressions in that the right operand
486 > is evaluated before the left one.
487
488 Otherwise, this expression is syntactic sugar for calling the function of the
489 overloading compound assigment trait of the operator (see the table earlier in
490 this chapter). A mutable borrow of the assigned operand is automatically taken.
491
492 For example, the following expression statements in `example` are equivalent:
493
494 ```rust
495 # struct Addable;
496 # use std::ops::AddAssign;
497
498 impl AddAssign<Addable> for Addable {
499 /* */
500 # fn add_assign(&mut self, other: Addable) {}
501 }
502
503 fn example() {
504 # let (mut a1, a2) = (Addable, Addable);
505 a1 += a2;
506
507 # let (mut a1, a2) = (Addable, Addable);
508 AddAssign::add_assign(&mut a1, a2);
509 }
510 ```
511
512 <div class="warning">
513
514 Warning: The evaluation order of operands swaps depending on the types of the
515 operands: with primitive types the right-hand side will get evaluated first,
516 while with non-primitive types the left-hand side will get evaluated first.
517 Try not to write code that depends on the evaluation order of operands in
518 compound assignment expressions. See [this test] for an example of using this
519 dependency.
520
521 </div>
522
523 [copies or moves]: ../expressions.md#moved-and-copied-types
524 [dropping]: ../destructors.md
525 [mutable]: ../expressions.md#mutability
526 [place expression]: ../expressions.md#place-expressions-and-value-expressions
527 [unit]: ../types/tuple.md
528 [value expression]: ../expressions.md#place-expressions-and-value-expressions
529 [temporary value]: ../expressions.md#temporaries
530 [this test]: https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs
531 [float-float]: https://github.com/rust-lang/rust/issues/15536
532 [Function pointer]: ../types/function-pointer.md
533 [Function item]: ../types/function-item.md
534
535 [_BorrowExpression_]: #borrow-operators
536 [_DereferenceExpression_]: #the-dereference-operator
537 [_ErrorPropagationExpression_]: #the-question-mark-operator
538 [_NegationExpression_]: #negation-operators
539 [_ArithmeticOrLogicalExpression_]: #arithmetic-and-logical-binary-operators
540 [_ComparisonExpression_]: #comparison-operators
541 [_LazyBooleanExpression_]: #lazy-boolean-operators
542 [_TypeCastExpression_]: #type-cast-expressions
543 [_AssignmentExpression_]: #assignment-expressions
544 [_CompoundAssignmentExpression_]: #compound-assignment-expressions
545
546 [_Expression_]: ../expressions.md
547 [_TypeNoBounds_]: ../types.md#type-expressions