2022-05-25 01:24:52 +00:00
|
|
|
|
<!-- DO NOT EDIT THIS FILE.
|
|
|
|
|
|
|
|
|
|
This file is periodically generated from the content in the `/src/`
|
|
|
|
|
directory, so all fixes need to be made in `/src/`.
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
[TOC]
|
|
|
|
|
|
|
|
|
|
## Appendix A: Keywords
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
The following lists contain keywords that are reserved for current or future
|
2022-05-25 01:24:52 +00:00
|
|
|
|
use by the Rust language. As such, they cannot be used as identifiers (except
|
2022-08-30 00:05:40 +00:00
|
|
|
|
as raw identifiers, as we’ll discuss in “Raw Identifiers” on page XX).
|
|
|
|
|
*Identifiers* are names of functions, variables, parameters, struct fields,
|
2022-06-08 13:08:54 +00:00
|
|
|
|
modules, crates, constants, macros, static values, attributes, types, traits,
|
|
|
|
|
or lifetimes.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Keywords Currently in Use
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-06-08 13:08:54 +00:00
|
|
|
|
The following is a list of keywords currently in use, with their functionality
|
|
|
|
|
described.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
* **`as` **: perform primitive casting, disambiguate the specific trait
|
|
|
|
|
containing an item, or rename items in `use` statements
|
|
|
|
|
* **`async` **: return a `Future` instead of blocking the current thread
|
|
|
|
|
* **`await` **: suspend execution until the result of a `Future` is ready
|
|
|
|
|
* **`break` **: exit a loop immediately
|
|
|
|
|
* **`const` **: define constant items or constant raw pointers
|
|
|
|
|
* **`continue` **: continue to the next loop iteration
|
|
|
|
|
* **`crate` **: in a module path, refers to the crate root
|
|
|
|
|
* **`dyn` **: dynamic dispatch to a trait object
|
|
|
|
|
* **`else` **: fallback for `if` and `if let` control flow constructs
|
|
|
|
|
* **`enum` **: define an enumeration
|
|
|
|
|
* **`extern` **: link an external function or variable
|
|
|
|
|
* **`false` **: Boolean false literal
|
|
|
|
|
* **`fn` **: define a function or the function pointer type
|
|
|
|
|
* **`for` **: loop over items from an iterator, implement a trait, or specify a
|
2022-08-30 00:05:40 +00:00
|
|
|
|
higher-ranked lifetime
|
2022-09-13 17:40:52 +00:00
|
|
|
|
* **`if` **: branch based on the result of a conditional expression
|
|
|
|
|
* **`impl` **: implement inherent or trait functionality
|
|
|
|
|
* **`in` **: part of `for` loop syntax
|
|
|
|
|
* **`let` **: bind a variable
|
|
|
|
|
* **`loop` **: loop unconditionally
|
|
|
|
|
* **`match` **: match a value to patterns
|
|
|
|
|
* **`mod` **: define a module
|
|
|
|
|
* **`move` **: make a closure take ownership of all its captures
|
|
|
|
|
* **`mut` **: denote mutability in references, raw pointers, or pattern bindings
|
|
|
|
|
* **`pub` **: denote public visibility in struct fields, `impl` blocks, or
|
|
|
|
|
modules
|
|
|
|
|
* **`ref` **: bind by reference
|
|
|
|
|
* **`return` **: return from function
|
|
|
|
|
* **`Self` **: a type alias for the type we are defining or implementing
|
|
|
|
|
* **`self` **: method subject or current module
|
|
|
|
|
* **`static` **: global variable or lifetime lasting the entire program
|
|
|
|
|
execution
|
|
|
|
|
* **`struct` **: define a structure
|
|
|
|
|
* **`super` **: parent module of the current module
|
|
|
|
|
* **`trait` **: define a trait
|
|
|
|
|
* **`true` **: Boolean true literal
|
|
|
|
|
* **`type` **: define a type alias or associated type
|
|
|
|
|
* **`union` **: define a union; is a keyword only when used in a union
|
|
|
|
|
declaration
|
|
|
|
|
* **`unsafe` **: denote unsafe code, functions, traits, or implementations
|
|
|
|
|
* **`use` **: bring symbols into scope
|
|
|
|
|
* **`where` **: denote clauses that constrain a type
|
|
|
|
|
* **`while` **: loop conditionally based on the result of an expression
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
## Keywords Reserved for Future Use
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
The following keywords do not yet have any functionality but are reserved by
|
|
|
|
|
Rust for potential future use:
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
* `abstract`
|
|
|
|
|
* `become`
|
|
|
|
|
* `box`
|
|
|
|
|
* `do`
|
|
|
|
|
* `final`
|
|
|
|
|
* `macro`
|
|
|
|
|
* `override`
|
|
|
|
|
* `priv`
|
|
|
|
|
* `try`
|
|
|
|
|
* `typeof`
|
|
|
|
|
* `unsized`
|
|
|
|
|
* `virtual`
|
|
|
|
|
* `yield`
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
## Raw Identifiers
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
*Raw identifiers* are the syntax that lets you use keywords where they wouldn’t
|
|
|
|
|
normally be allowed. You use a raw identifier by prefixing a keyword with `r#`.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
For example, `match` is a keyword. If you try to compile the following function
|
|
|
|
|
that uses `match` as its name:
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Filename: src/main.rs
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
```
|
|
|
|
|
fn match(needle: &str, haystack: &str) -> bool {
|
|
|
|
|
haystack.contains(needle)
|
|
|
|
|
}
|
|
|
|
|
```
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
you’ll get this error:
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
```
|
|
|
|
|
error: expected identifier, found keyword `match`
|
|
|
|
|
--> src/main.rs:4:4
|
|
|
|
|
|
|
|
|
|
|
4 | fn match(needle: &str, haystack: &str) -> bool {
|
|
|
|
|
| ^^^^^ expected identifier, found keyword
|
|
|
|
|
```
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
The error shows that you can’t use the keyword `match` as the function
|
|
|
|
|
identifier. To use `match` as a function name, you need to use the raw
|
|
|
|
|
identifier syntax, like this:
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Filename: src/main.rs
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
```
|
|
|
|
|
fn r#match(needle: &str, haystack: &str) -> bool {
|
|
|
|
|
haystack.contains(needle)
|
|
|
|
|
}
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
fn main() {
|
|
|
|
|
assert!(r#match("foo", "foobar"));
|
|
|
|
|
}
|
|
|
|
|
```
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
This code will compile without any errors. Note the `r#` prefix on the function
|
|
|
|
|
name in its definition as well as where the function is called in `main`.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Raw identifiers allow you to use any word you choose as an identifier, even if
|
|
|
|
|
that word happens to be a reserved keyword. This gives us more freedom to
|
|
|
|
|
choose identifier names, as well as lets us integrate with programs written in
|
|
|
|
|
a language where these words aren’t keywords. In addition, raw identifiers
|
|
|
|
|
allow you to use libraries written in a different Rust edition than your crate
|
|
|
|
|
uses. For example, `try` isn’t a keyword in the 2015 edition but is in the 2018
|
|
|
|
|
and 2021 editions. If you depend on a library that is written using the 2015
|
|
|
|
|
edition and has a `try` function, you’ll need to use the raw identifier syntax,
|
|
|
|
|
`r#try` in this case, to call that function from your 2021 edition code. See
|
|
|
|
|
Appendix E for more information on editions.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
## Appendix B: Operators and Symbols
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
This appendix contains a glossary of Rust’s syntax, including operators and
|
|
|
|
|
other symbols that appear by themselves or in the context of paths, generics,
|
|
|
|
|
trait bounds, macros, attributes, comments, tuples, and brackets.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
## Operators
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-1 contains the operators in Rust, an example of how the operator would
|
|
|
|
|
appear in context, a short explanation, and whether that operator is
|
|
|
|
|
overloadable. If an operator is overloadable, the relevant trait to use to
|
|
|
|
|
overload that operator is listed.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-1: Operators
|
|
|
|
|
|
|
|
|
|
| Operator | Example | Explanation | Overloadable? |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| `!` | `ident!(...)`, `ident!{...}`, `ident![...]` | Macro expansion | |
|
|
|
|
|
| `!` | `!expr` | Bitwise or logical complement | `Not` |
|
|
|
|
|
| `!=` | `expr != expr` | Nonequality comparison | `PartialEq` |
|
|
|
|
|
| `% | `expr % expr` | Arithmetic remainder | `Rem` |
|
|
|
|
|
| `%=` | `var %= expr` | Arithmetic remainder and assignment | `RemAssign` |
|
|
|
|
|
| `& | `&expr`, `&mut expr` | Borrow | |
|
|
|
|
|
| `&` | `&type`, `&mut type`, `&'a type`, `&'a mut type` | Borrowed pointer
|
|
|
|
|
type | |
|
|
|
|
|
| `&` | `expr & expr` | Bitwise AND | `BitAnd` |
|
|
|
|
|
| `&=` | `var &= expr` | Bitwise AND and assignment | `BitAndAssign` |
|
|
|
|
|
| `&&` | `expr && expr` | Short-circuiting logical AND | |
|
|
|
|
|
| `* | `expr * expr` | Arithmetic multiplication | `Mul` |
|
|
|
|
|
| `*=` | `var *= expr` | Arithmetic multiplication and assignment | `MulAssign`
|
|
|
|
|
|
|
|
|
|
|
| `*` | `*expr` | Dereference | `Deref` |
|
|
|
|
|
| `*` | `*const type`, `*mut type | Raw pointer | |
|
|
|
|
|
| `+ | `trait + trait`, `'a + trait` | Compound type constraint | |
|
|
|
|
|
| `+ | `expr + expr` | Arithmetic addition | `Add` |
|
|
|
|
|
| `+=` | `var += expr` | Arithmetic addition and assignment | `AddAssign` |
|
|
|
|
|
| `,` | `expr, expr` | Argument and element separator | |
|
|
|
|
|
| `- | `- expr` | Arithmetic negation | `Neg` |
|
|
|
|
|
| `- | `expr - expr` | Arithmetic subtraction | `Sub` |
|
|
|
|
|
| `-=` | `var -= expr` | Arithmetic subtraction and assignment | `SubAssign` |
|
|
|
|
|
| `-> | `fn(...) -> type`, `|…| -> type` | Function and closure return type | |
|
|
|
|
|
| `. | `expr.ident` | Member access | |
|
|
|
|
|
| `..` | `..`, `expr..`, `..expr`, `expr..expr` | Right-exclusive range literal
|
|
|
|
|
| `PartialOrd` |
|
|
|
|
|
| `..=` | `..=expr`, `expr..=expr` | Right-inclusive range literal |
|
|
|
|
|
`PartialOrd` |
|
|
|
|
|
| `..` | `..expr` | Struct literal update syntax | |
|
|
|
|
|
| `..` | `variant(x, ..)`, `struct_type { x, .. }` | “And the rest” pattern
|
|
|
|
|
binding | |
|
|
|
|
|
| `...` | `expr...expr` | (Deprecated, use `..=` instead) In a pattern:
|
|
|
|
|
inclusive range pattern | |
|
|
|
|
|
| `/ | `expr / expr` | Arithmetic division | `Div` |
|
|
|
|
|
| `/=` | `var /= expr` | Arithmetic division and assignment | `DivAssign` |
|
|
|
|
|
| `: | `pat: type`, `ident: type` | Constraints | |
|
|
|
|
|
| `:` | `ident: expr` | Struct field initializer | |
|
|
|
|
|
| `:` | `'a: loop {...}` | Loop label | |
|
|
|
|
|
| `; | `expr;` | Statement and item terminator | |
|
|
|
|
|
| `;` | `[...; len]` | Part of fixed-size array syntax | |
|
|
|
|
|
| `<<` | `expr << expr` | Left-shift | `Shl` |
|
|
|
|
|
| `<<=` | `var <<= expr` | Left-shift and assignment | `ShlAssign` |
|
|
|
|
|
| `<` | `expr < expr` | Less than comparison | `PartialOrd` |
|
|
|
|
|
| `<=` | `expr <= expr` | Less than or equal to comparison | `PartialOrd` |
|
|
|
|
|
| `=` | `var = expr`, `ident = type` | Assignment/equivalence | |
|
|
|
|
|
| `==` | `expr == expr` | Equality comparison | `PartialEq` |
|
|
|
|
|
| `=>` | `pat => expr` | Part of match arm syntax | |
|
|
|
|
|
| `>` | `expr > expr` | Greater than comparison | `PartialOrd` |
|
|
|
|
|
| `>=` | `expr >= expr` | Greater than or equal to comparison | `PartialOrd` |
|
|
|
|
|
| `>>` | `expr >> expr` | Right-shift | `Shr` |
|
|
|
|
|
| `>>=` | `var >>= expr` | Right-shift and assignment | `ShrAssign` |
|
|
|
|
|
| `@ | `ident @ pat` | Pattern binding | |
|
|
|
|
|
| `^` | `expr ^ expr` | Bitwise exclusive OR | `BitXor` |
|
|
|
|
|
| `^=` | `var ^= expr` | Bitwise exclusive OR and assignment | `BitXorAssign` |
|
|
|
|
|
| `| | `pat | pat` | Pattern alternatives | |
|
|
|
|
|
| `|` | `expr | expr` | Bitwise OR | `BitOr` |
|
|
|
|
|
| `|=` | `var |= expr` | Bitwise OR and assignment | `BitOrAssign` |
|
|
|
|
|
| `||` | `expr || expr` | Short-circuiting logical OR | |
|
|
|
|
|
| `? | `expr?` | Error propagation | |
|
|
|
|
|
|
|
|
|
|
## Non-operator Symbols
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
The following tables contain all symbols that don’t function as operators; that
|
|
|
|
|
is, they don’t behave like a function or method call.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-2 shows symbols that appear on their own and are valid in a variety of
|
|
|
|
|
locations.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-2: Stand-Alone Syntax
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `'ident | Named lifetime or loop label |
|
|
|
|
|
| `...u8`, `...i32`, `...f64`, `...usize`, and so on | Numeric literal of
|
|
|
|
|
specific type |
|
|
|
|
|
| `"..." | String literal |
|
|
|
|
|
| `r"..."`, `r#"..."#`, `r##"..."##`, and so on | Raw string literal; escape
|
|
|
|
|
characters not processed |
|
|
|
|
|
| `b"..."` | Byte string literal; constructs an array of bytes instead of a
|
|
|
|
|
string |
|
|
|
|
|
| `br"..."`, `br#"..."#`, `br##"..."##`, and so on | Raw byte string literal;
|
|
|
|
|
combination of raw and byte string literal |
|
|
|
|
|
| `'...' | Character literal |
|
|
|
|
|
| `b'...' | ASCII byte literal |
|
|
|
|
|
| `|…| expr | Closure |
|
|
|
|
|
| `! | Always-empty bottom type for diverging functions |
|
|
|
|
|
| `_ | “Ignored” pattern binding; also used to make integer literals readable |
|
|
|
|
|
|
|
|
|
|
Table B-3 shows symbols that appear in the context of a path through the module
|
|
|
|
|
hierarchy to an item.
|
|
|
|
|
|
|
|
|
|
Table B-3: Path-Related Syntax
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `ident::ident | Namespace path |
|
|
|
|
|
| `::path` | Path relative to the crate root (that is, an explicitly absolute
|
|
|
|
|
path) |
|
|
|
|
|
| `self::path` | Path relative to the current module (that is, an explicitly
|
|
|
|
|
relative path) |
|
|
|
|
|
| `super::path` | Path relative to the parent of the current module |
|
|
|
|
|
| `type::ident`, `<type as trait>::ident | Associated constants, functions, and
|
|
|
|
|
types |
|
|
|
|
|
| `<type>::...` | Associated item for a type that cannot be directly named (for
|
|
|
|
|
example, `<&T>::...`, `<[T]>::...`, and so on) |
|
|
|
|
|
| `trait::method(...)` | Disambiguating a method call by naming the trait that
|
|
|
|
|
defines it |
|
|
|
|
|
| `type::method(...)` | Disambiguating a method call by naming the type for
|
|
|
|
|
which it’s defined |
|
|
|
|
|
| `<type as trait>::method(...)` | Disambiguating a method call by naming the
|
|
|
|
|
trait and type |
|
|
|
|
|
|
|
|
|
|
Table B-4 shows symbols that appear in the context of using generic type
|
|
|
|
|
parameters.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-4: Generics
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `path<...>` | Specifies parameters to a generic type in a type (for example,
|
|
|
|
|
`Vec<u8>`) |
|
|
|
|
|
| `path::<...>, method::<...>` | Specifies parameters to a generic type,
|
|
|
|
|
function, or method in an expression; often referred to as turbofish (for
|
|
|
|
|
example, `"42".parse::<i32>()`) |
|
|
|
|
|
| `fn ident<...> ...` | Define generic function |
|
|
|
|
|
| `struct ident<...> ...` | Define generic structure |
|
|
|
|
|
| `enum ident<...> ...` | Define generic enumeration |
|
|
|
|
|
| `impl<...> ...` | Define generic implementation |
|
|
|
|
|
| `for<...> type` | Higher-ranked lifetime bounds |
|
|
|
|
|
| `type<ident=type>` | A generic type where one or more associated types have
|
|
|
|
|
specific assignments (for example, `Iterator<Item=T>`) |
|
|
|
|
|
|
|
|
|
|
Table B-5 shows symbols that appear in the context of constraining generic type
|
|
|
|
|
parameters with trait bounds.
|
|
|
|
|
|
|
|
|
|
Table B-5: Trait Bound Constraints
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| T: U` | Generic parameter `T` constrained to types that implement `U` |
|
|
|
|
|
| `T: 'a` | Generic type `T` must outlive lifetime `'a` (meaning the type
|
|
|
|
|
cannot transitively contain any references with lifetimes shorter than `'a`) |
|
|
|
|
|
| `T: 'static` | Generic type `T` contains no borrowed references other than
|
|
|
|
|
`'static` ones |
|
|
|
|
|
| `'b: 'a` | Generic lifetime `'b` must outlive lifetime `'a` |
|
|
|
|
|
| `T: ?Sized` | Allow generic type parameter to be a dynamically sized type |
|
|
|
|
|
| `'a + trait`, `trait + trait` | Compound type constraint |
|
|
|
|
|
|
|
|
|
|
Table B-6 shows symbols that appear in the context of calling or defining
|
|
|
|
|
macros and specifying attributes on an item.
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Table B-6: Macros and Attributes
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `#[meta]` | Outer attribute |
|
|
|
|
|
| `#![meta]` | Inner attribute |
|
|
|
|
|
| `$ident` | Macro substitution |
|
|
|
|
|
| `$ident:kind` | Macro capture |
|
|
|
|
|
| `$(…)…` | Macro repetition |
|
|
|
|
|
| `ident!(...)`, `ident!{...}`, `ident![...]` | Macro invocation |
|
|
|
|
|
|
|
|
|
|
Table B-7 shows symbols that create comments.
|
|
|
|
|
|
|
|
|
|
Table B-7: Comments
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `//` | Line comment |
|
|
|
|
|
| `//!` | Inner line doc comment |
|
|
|
|
|
| `///` | Outer line doc comment |
|
|
|
|
|
| `/*...*/` | Block comment |
|
|
|
|
|
| `/*!...*/` | Inner block doc comment |
|
|
|
|
|
| `/**...*/` | Outer block doc comment |
|
|
|
|
|
|
|
|
|
|
Table B-8 shows symbols that appear in the context of using tuples.
|
|
|
|
|
|
|
|
|
|
Table B-8: Tuples
|
|
|
|
|
|
|
|
|
|
| Symbol | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `() | Empty tuple (aka unit), both literal and type |
|
|
|
|
|
| `(expr)` | Parenthesized expression |
|
|
|
|
|
| `(expr,)` | Single-element tuple expression |
|
|
|
|
|
| `(type,)` | Single-element tuple type |
|
|
|
|
|
| `(expr, ...)` | Tuple expression |
|
|
|
|
|
| `(type, ...)` | Tuple type |
|
|
|
|
|
| `expr(expr, ...)` | Function call expression; also used to initialize tuple
|
|
|
|
|
`struct`s and tuple `enum` variants |
|
|
|
|
|
| `expr.0`, `expr.1`, and so on | Tuple indexing |
|
|
|
|
|
|
|
|
|
|
Table B-9 shows the contexts in which curly brackets are used.
|
|
|
|
|
|
|
|
|
|
Table B-9: Curly Brackets
|
|
|
|
|
|
|
|
|
|
| Context | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `{...}` | Block expression |
|
|
|
|
|
| `Type {...}` | `struct` literal |
|
|
|
|
|
|
|
|
|
|
Table B-10 shows the contexts in which square brackets are used.
|
|
|
|
|
|
|
|
|
|
Table B-10: Square Brackets
|
|
|
|
|
|
|
|
|
|
| Context | Explanation |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `[...]` | Array literal |
|
|
|
|
|
| `[expr; len]` | Array literal containing `len` copies of `expr` |
|
|
|
|
|
| `[type; len]` | Array type containing `len` instances of `type` |
|
|
|
|
|
| `expr[expr]` | Collection indexing; overloadable (`Index`, `IndexMut`) |
|
|
|
|
|
| `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]` | Collection indexing
|
|
|
|
|
pretending to be collection slicing, using `Range`, `RangeFrom`, `RangeTo`, or
|
|
|
|
|
`RangeFull` as the “index” |
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
## Appendix C: Derivable Traits
|
|
|
|
|
|
|
|
|
|
In various places in the book, we’ve discussed the `derive` attribute, which
|
|
|
|
|
you can apply to a struct or enum definition. The `derive` attribute generates
|
|
|
|
|
code that will implement a trait with its own default implementation on the
|
|
|
|
|
type you’ve annotated with the `derive` syntax.
|
|
|
|
|
|
|
|
|
|
In this appendix, we provide a reference of all the traits in the standard
|
|
|
|
|
library that you can use with `derive`. Each section covers:
|
|
|
|
|
|
|
|
|
|
* What operators and methods deriving this trait will enable
|
|
|
|
|
* What the implementation of the trait provided by `derive` does
|
|
|
|
|
* What implementing the trait signifies about the type
|
|
|
|
|
* The conditions in which you’re allowed or not allowed to implement the trait
|
|
|
|
|
* Examples of operations that require the trait
|
2022-09-13 17:40:52 +00:00
|
|
|
|
|
2022-05-25 01:24:52 +00:00
|
|
|
|
If you want different behavior from that provided by the `derive` attribute,
|
2022-08-30 00:05:40 +00:00
|
|
|
|
consult the standard library documentation for each trait for details on how to
|
2022-06-08 13:08:54 +00:00
|
|
|
|
manually implement them.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
The traits listed here are the only ones defined by the standard library that
|
|
|
|
|
can be implemented on your types using `derive`. Other traits defined in the
|
|
|
|
|
standard library don’t have sensible default behavior, so it’s up to you to
|
|
|
|
|
implement them in the way that makes sense for what you’re trying to accomplish.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
An example of a trait that can’t be derived is `Display`, which handles
|
|
|
|
|
formatting for end users. You should always consider the appropriate way to
|
|
|
|
|
display a type to an end user. What parts of the type should an end user be
|
|
|
|
|
allowed to see? What parts would they find relevant? What format of the data
|
|
|
|
|
would be most relevant to them? The Rust compiler doesn’t have this insight, so
|
|
|
|
|
it can’t provide appropriate default behavior for you.
|
|
|
|
|
|
|
|
|
|
The list of derivable traits provided in this appendix is not comprehensive:
|
|
|
|
|
libraries can implement `derive` for their own traits, making the list of
|
2022-08-30 00:05:40 +00:00
|
|
|
|
traits you can use `derive` with truly open ended. Implementing `derive`
|
|
|
|
|
involves using a procedural macro, which is covered in “Macros” on page XX.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Debug for Programmer Output
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Debug` trait enables debug formatting in format strings, which you
|
|
|
|
|
indicate by adding `:?` within `{}` placeholders.
|
|
|
|
|
|
|
|
|
|
The `Debug` trait allows you to print instances of a type for debugging
|
|
|
|
|
purposes, so you and other programmers using your type can inspect an instance
|
|
|
|
|
at a particular point in a program’s execution.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
The `Debug` trait is required, for example, in the use of the `assert_eq!`
|
|
|
|
|
macro. This macro prints the values of instances given as arguments if the
|
|
|
|
|
equality assertion fails so programmers can see why the two instances weren’t
|
|
|
|
|
equal.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## PartialEq and Eq for Equality Comparisons
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `PartialEq` trait allows you to compare instances of a type to check for
|
|
|
|
|
equality and enables use of the `==` and `!=` operators.
|
|
|
|
|
|
|
|
|
|
Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on
|
|
|
|
|
structs, two instances are equal only if *all* fields are equal, and the
|
|
|
|
|
instances are not equal if any fields are not equal. When derived on enums,
|
|
|
|
|
each variant is equal to itself and not equal to the other variants.
|
|
|
|
|
|
|
|
|
|
The `PartialEq` trait is required, for example, with the use of the
|
|
|
|
|
`assert_eq!` macro, which needs to be able to compare two instances of a type
|
|
|
|
|
for equality.
|
|
|
|
|
|
|
|
|
|
The `Eq` trait has no methods. Its purpose is to signal that for every value of
|
|
|
|
|
the annotated type, the value is equal to itself. The `Eq` trait can only be
|
|
|
|
|
applied to types that also implement `PartialEq`, although not all types that
|
2022-08-30 00:05:40 +00:00
|
|
|
|
implement `PartialEq` can implement `Eq`. One example of this is floating-point
|
|
|
|
|
number types: the implementation of floating-point numbers states that two
|
2022-05-25 01:24:52 +00:00
|
|
|
|
instances of the not-a-number (`NaN`) value are not equal to each other.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
An example of when `Eq` is required is for keys in a `HashMap<K, V>` so that
|
|
|
|
|
the `HashMap<K, V>` can tell whether two keys are the same.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## PartialOrd and Ord for Ordering Comparisons
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `PartialOrd` trait allows you to compare instances of a type for sorting
|
|
|
|
|
purposes. A type that implements `PartialOrd` can be used with the `<`, `>`,
|
|
|
|
|
`<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types
|
|
|
|
|
that also implement `PartialEq`.
|
|
|
|
|
|
|
|
|
|
Deriving `PartialOrd` implements the `partial_cmp` method, which returns an
|
|
|
|
|
`Option<Ordering>` that will be `None` when the values given don’t produce an
|
|
|
|
|
ordering. An example of a value that doesn’t produce an ordering, even though
|
|
|
|
|
most values of that type can be compared, is the not-a-number (`NaN`) floating
|
2022-08-30 00:05:40 +00:00
|
|
|
|
point value. Calling `partial_cmp` with any floating-point number and the `NaN`
|
|
|
|
|
floating-point value will return `None`.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
When derived on structs, `PartialOrd` compares two instances by comparing the
|
|
|
|
|
value in each field in the order in which the fields appear in the struct
|
|
|
|
|
definition. When derived on enums, variants of the enum declared earlier in the
|
|
|
|
|
enum definition are considered less than the variants listed later.
|
|
|
|
|
|
|
|
|
|
The `PartialOrd` trait is required, for example, for the `gen_range` method
|
|
|
|
|
from the `rand` crate that generates a random value in the range specified by a
|
|
|
|
|
range expression.
|
|
|
|
|
|
|
|
|
|
The `Ord` trait allows you to know that for any two values of the annotated
|
|
|
|
|
type, a valid ordering will exist. The `Ord` trait implements the `cmp` method,
|
|
|
|
|
which returns an `Ordering` rather than an `Option<Ordering>` because a valid
|
|
|
|
|
ordering will always be possible. You can only apply the `Ord` trait to types
|
|
|
|
|
that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When
|
|
|
|
|
derived on structs and enums, `cmp` behaves the same way as the derived
|
|
|
|
|
implementation for `partial_cmp` does with `PartialOrd`.
|
|
|
|
|
|
|
|
|
|
An example of when `Ord` is required is when storing values in a `BTreeSet<T>`,
|
|
|
|
|
a data structure that stores data based on the sort order of the values.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Clone and Copy for Duplicating Values
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Clone` trait allows you to explicitly create a deep copy of a value, and
|
|
|
|
|
the duplication process might involve running arbitrary code and copying heap
|
2022-09-13 17:40:52 +00:00
|
|
|
|
data. See “Variables and Data Interacting with Clone” on page XX for more
|
2022-08-30 00:05:40 +00:00
|
|
|
|
information on `Clone`.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
Deriving `Clone` implements the `clone` method, which when implemented for the
|
|
|
|
|
whole type, calls `clone` on each of the parts of the type. This means all the
|
|
|
|
|
fields or values in the type must also implement `Clone` to derive `Clone`.
|
|
|
|
|
|
|
|
|
|
An example of when `Clone` is required is when calling the `to_vec` method on a
|
|
|
|
|
slice. The slice doesn’t own the type instances it contains, but the vector
|
|
|
|
|
returned from `to_vec` will need to own its instances, so `to_vec` calls
|
2022-08-30 00:05:40 +00:00
|
|
|
|
`clone` on each item. Thus the type stored in the slice must implement `Clone`.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Copy` trait allows you to duplicate a value by only copying bits stored on
|
2022-08-30 00:05:40 +00:00
|
|
|
|
the stack; no arbitrary code is necessary. See “Stack-Only Data: Copy” on page
|
|
|
|
|
XX for more information on `Copy`.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Copy` trait doesn’t define any methods to prevent programmers from
|
|
|
|
|
overloading those methods and violating the assumption that no arbitrary code
|
|
|
|
|
is being run. That way, all programmers can assume that copying a value will be
|
|
|
|
|
very fast.
|
|
|
|
|
|
|
|
|
|
You can derive `Copy` on any type whose parts all implement `Copy`. A type that
|
2022-08-30 00:05:40 +00:00
|
|
|
|
implements `Copy` must also implement `Clone` because a type that implements
|
2022-05-25 01:24:52 +00:00
|
|
|
|
`Copy` has a trivial implementation of `Clone` that performs the same task as
|
|
|
|
|
`Copy`.
|
|
|
|
|
|
|
|
|
|
The `Copy` trait is rarely required; types that implement `Copy` have
|
|
|
|
|
optimizations available, meaning you don’t have to call `clone`, which makes
|
|
|
|
|
the code more concise.
|
|
|
|
|
|
|
|
|
|
Everything possible with `Copy` you can also accomplish with `Clone`, but the
|
|
|
|
|
code might be slower or have to use `clone` in places.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Hash for Mapping a Value to a Value of Fixed Size
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Hash` trait allows you to take an instance of a type of arbitrary size and
|
|
|
|
|
map that instance to a value of fixed size using a hash function. Deriving
|
|
|
|
|
`Hash` implements the `hash` method. The derived implementation of the `hash`
|
|
|
|
|
method combines the result of calling `hash` on each of the parts of the type,
|
|
|
|
|
meaning all fields or values must also implement `Hash` to derive `Hash`.
|
|
|
|
|
|
|
|
|
|
An example of when `Hash` is required is in storing keys in a `HashMap<K, V>`
|
|
|
|
|
to store data efficiently.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Default for Default Values
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The `Default` trait allows you to create a default value for a type. Deriving
|
|
|
|
|
`Default` implements the `default` function. The derived implementation of the
|
|
|
|
|
`default` function calls the `default` function on each part of the type,
|
|
|
|
|
meaning all fields or values in the type must also implement `Default` to
|
|
|
|
|
derive `Default`.
|
|
|
|
|
|
|
|
|
|
The `Default::default` function is commonly used in combination with the struct
|
2022-08-30 00:05:40 +00:00
|
|
|
|
update syntax discussed in “Creating Instances from Other Instances with Struct
|
|
|
|
|
Update Syntax” on page XX. You can customize a few fields of a struct and then
|
|
|
|
|
set and use a default value for the rest of the fields by using
|
2022-05-25 01:24:52 +00:00
|
|
|
|
`..Default::default()`.
|
|
|
|
|
|
|
|
|
|
The `Default` trait is required when you use the method `unwrap_or_default` on
|
|
|
|
|
`Option<T>` instances, for example. If the `Option<T>` is `None`, the method
|
|
|
|
|
`unwrap_or_default` will return the result of `Default::default` for the type
|
|
|
|
|
`T` stored in the `Option<T>`.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Appendix D: Useful Development Tools
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
In this appendix, we talk about some useful development tools that the Rust
|
|
|
|
|
project provides. We’ll look at automatic formatting, quick ways to apply
|
|
|
|
|
warning fixes, a linter, and integrating with IDEs.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Automatic Formatting with rustfmt
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-06-08 13:08:54 +00:00
|
|
|
|
The `rustfmt` tool reformats your code according to the community code style.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
Many collaborative projects use `rustfmt` to prevent arguments about which
|
|
|
|
|
style to use when writing Rust: everyone formats their code using the tool.
|
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Rust installations include `rustfmt` by default, so you should already have the
|
|
|
|
|
programs `rustfmt` and `cargo-fmt` on your system. These two commands are
|
|
|
|
|
analagous to `rustc` and `cargo` in that `rustfmt` allows finer-grained control
|
|
|
|
|
and `cargo-fmt` understands conventions of a project that uses Cargo. To format
|
|
|
|
|
any Cargo project, enter the following:
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ cargo fmt
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Running this command reformats all the Rust code in the current crate. This
|
|
|
|
|
should only change the code style, not the code semantics. For more information
|
|
|
|
|
on `rustfmt`, see its documentation at *https://github.com/rust-lang/rustfmt*.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Fix Your Code with rustfix
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
The `rustfix` tool is included with Rust installations and can automatically
|
|
|
|
|
fix compiler warnings that have a clear way to correct the problem that’s
|
|
|
|
|
likely what you want. You’ve probably seen compiler warnings before. For
|
|
|
|
|
example, consider this code:
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
Filename: src/main.rs
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn do_something() {}
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-05-25 01:24:52 +00:00
|
|
|
|
fn main() {
|
|
|
|
|
for i in 0..100 {
|
|
|
|
|
do_something();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Here, we’re calling the `do_something` function 100 times, but we never use the
|
|
|
|
|
variable `i` in the body of the `for` loop. Rust warns us about that:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ cargo build
|
|
|
|
|
Compiling myprogram v0.1.0 (file:///projects/myprogram)
|
|
|
|
|
warning: unused variable: `i`
|
|
|
|
|
--> src/main.rs:4:9
|
|
|
|
|
|
|
|
|
|
|
4 | for i in 0..100 {
|
|
|
|
|
| ^ help: consider using `_i` instead
|
|
|
|
|
|
|
|
|
|
|
= note: #[warn(unused_variables)] on by default
|
2022-08-30 00:05:40 +00:00
|
|
|
|
|
2022-05-25 01:24:52 +00:00
|
|
|
|
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The warning suggests that we use `_i` as a name instead: the underscore
|
|
|
|
|
indicates that we intend for this variable to be unused. We can automatically
|
|
|
|
|
apply that suggestion using the `rustfix` tool by running the command `cargo
|
|
|
|
|
fix`:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ cargo fix
|
|
|
|
|
Checking myprogram v0.1.0 (file:///projects/myprogram)
|
|
|
|
|
Fixing src/main.rs (1 fix)
|
|
|
|
|
Finished dev [unoptimized + debuginfo] target(s) in 0.59s
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When we look at *src/main.rs* again, we’ll see that `cargo fix` has changed the
|
|
|
|
|
code:
|
|
|
|
|
|
|
|
|
|
Filename: src/main.rs
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn do_something() {}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
for _i in 0..100 {
|
|
|
|
|
do_something();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `for` loop variable is now named `_i`, and the warning no longer appears.
|
|
|
|
|
|
|
|
|
|
You can also use the `cargo fix` command to transition your code between
|
|
|
|
|
different Rust editions. Editions are covered in Appendix E.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## More Lints with Clippy
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
The Clippy tool is a collection of lints to analyze your code so you can catch
|
2022-09-13 17:40:52 +00:00
|
|
|
|
common mistakes and improve your Rust code. Clippy is included with standard
|
|
|
|
|
Rust installations.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
To run Clippy’s lints on any Cargo project, enter the following:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ cargo clippy
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For example, say you write a program that uses an approximation of a
|
|
|
|
|
mathematical constant, such as pi, as this program does:
|
|
|
|
|
|
|
|
|
|
Filename: src/main.rs
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = 3.1415;
|
|
|
|
|
let r = 8.0;
|
|
|
|
|
println!("the area of the circle is {}", x * r * r);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Running `cargo clippy` on this project results in this error:
|
|
|
|
|
|
|
|
|
|
```
|
2022-09-13 17:40:52 +00:00
|
|
|
|
error: approximate value of `f{32, 64}::consts::PI` found
|
2022-05-25 01:24:52 +00:00
|
|
|
|
--> src/main.rs:2:13
|
|
|
|
|
|
|
|
|
|
|
2 | let x = 3.1415;
|
|
|
|
|
| ^^^^^^
|
|
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
= note: `#[deny(clippy::approx_constant)]` on by default
|
|
|
|
|
= help: consider using the constant directly
|
|
|
|
|
= help: for further information visit https://rust-lang.github.io/rust-
|
|
|
|
|
clippy/master/index.html#approx_constant
|
2022-05-25 01:24:52 +00:00
|
|
|
|
```
|
|
|
|
|
|
2022-06-08 13:08:54 +00:00
|
|
|
|
This error lets you know that Rust already has a more precise `PI` constant
|
|
|
|
|
defined, and that your program would be more correct if you used the constant
|
|
|
|
|
instead. You would then change your code to use the `PI` constant.
|
2022-06-20 01:01:57 +00:00
|
|
|
|
|
2022-06-08 13:08:54 +00:00
|
|
|
|
The following code doesn’t result in any errors or warnings from Clippy:
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-09-13 17:40:52 +00:00
|
|
|
|
Filename: src/main.rs
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = std::f64::consts::PI;
|
|
|
|
|
let r = 8.0;
|
|
|
|
|
println!("the area of the circle is {}", x * r * r);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
For more information on Clippy, see its documentation at
|
|
|
|
|
*https://github.com/rust-lang/rust-clippy**.*
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## IDE Integration Using rust-analyzer
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
To help with IDE integration, the Rust community recommends using
|
|
|
|
|
`rust-analyzer`. This tool is a set of compiler-centric utilities that speak
|
|
|
|
|
Language Server Protocol, which is a specification for IDEs and programming
|
|
|
|
|
languages to communicate with each other. Different clients can use
|
|
|
|
|
`rust-analyzer`, such as the Rust analyzer plug-in for Visual Studio Code at
|
2022-05-25 01:24:52 +00:00
|
|
|
|
*https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer*.
|
|
|
|
|
|
|
|
|
|
Visit the `rust-analyzer` project’s home page at
|
|
|
|
|
*https://rust-analyzer.github.io* for installation instructions, then install
|
|
|
|
|
the language server support in your particular IDE. Your IDE will gain
|
2022-09-13 17:40:52 +00:00
|
|
|
|
capabilities such as autocompletion, jump to definition, and inline errors
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
## Appendix E: Editions
|
2022-05-25 01:24:52 +00:00
|
|
|
|
|
|
|
|
|
In Chapter 1, you saw that `cargo new` adds a bit of metadata to your
|
|
|
|
|
*Cargo.toml* file about an edition. This appendix talks about what that means!
|
|
|
|
|
|
|
|
|
|
The Rust language and compiler have a six-week release cycle, meaning users get
|
|
|
|
|
a constant stream of new features. Other programming languages release larger
|
|
|
|
|
changes less often; Rust releases smaller updates more frequently. After a
|
|
|
|
|
while, all of these tiny changes add up. But from release to release, it can be
|
|
|
|
|
difficult to look back and say, “Wow, between Rust 1.10 and Rust 1.31, Rust has
|
|
|
|
|
changed a lot!”
|
|
|
|
|
|
|
|
|
|
Every two or three years, the Rust team produces a new Rust *edition*. Each
|
|
|
|
|
edition brings together the features that have landed into a clear package with
|
|
|
|
|
fully updated documentation and tooling. New editions ship as part of the usual
|
|
|
|
|
six-week release process.
|
|
|
|
|
|
|
|
|
|
Editions serve different purposes for different people:
|
|
|
|
|
|
|
|
|
|
* For active Rust users, a new edition brings together incremental changes into
|
2022-08-30 00:05:40 +00:00
|
|
|
|
an easy-to-understand package.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
* For non-users, a new edition signals that some major advancements have
|
2022-08-30 00:05:40 +00:00
|
|
|
|
landed, which might make Rust worth another look.
|
2022-05-25 01:24:52 +00:00
|
|
|
|
* For those developing Rust, a new edition provides a rallying point for the
|
2022-08-30 00:05:40 +00:00
|
|
|
|
project as a whole.
|
2022-09-13 17:40:52 +00:00
|
|
|
|
|
2022-05-25 01:24:52 +00:00
|
|
|
|
At the time of this writing, three Rust editions are available: Rust 2015, Rust
|
|
|
|
|
2018, and Rust 2021. This book is written using Rust 2021 edition idioms.
|
|
|
|
|
|
|
|
|
|
The `edition` key in *Cargo.toml* indicates which edition the compiler should
|
|
|
|
|
use for your code. If the key doesn’t exist, Rust uses `2015` as the edition
|
|
|
|
|
value for backward compatibility reasons.
|
|
|
|
|
|
|
|
|
|
Each project can opt in to an edition other than the default 2015 edition.
|
|
|
|
|
Editions can contain incompatible changes, such as including a new keyword that
|
|
|
|
|
conflicts with identifiers in code. However, unless you opt in to those
|
|
|
|
|
changes, your code will continue to compile even as you upgrade the Rust
|
|
|
|
|
compiler version you use.
|
|
|
|
|
|
|
|
|
|
All Rust compiler versions support any edition that existed prior to that
|
|
|
|
|
compiler’s release, and they can link crates of any supported editions
|
|
|
|
|
together. Edition changes only affect the way the compiler initially parses
|
|
|
|
|
code. Therefore, if you’re using Rust 2015 and one of your dependencies uses
|
|
|
|
|
Rust 2018, your project will compile and be able to use that dependency. The
|
|
|
|
|
opposite situation, where your project uses Rust 2018 and a dependency uses
|
|
|
|
|
Rust 2015, works as well.
|
|
|
|
|
|
|
|
|
|
To be clear: most features will be available on all editions. Developers using
|
|
|
|
|
any Rust edition will continue to see improvements as new stable releases are
|
|
|
|
|
made. However, in some cases, mainly when new keywords are added, some new
|
|
|
|
|
features might only be available in later editions. You will need to switch
|
|
|
|
|
editions if you want to take advantage of such features.
|
|
|
|
|
|
2022-08-30 00:05:40 +00:00
|
|
|
|
For more details, *The* *Edition Guide* at
|
|
|
|
|
*https://doc.rust-lang.org/stable/edition-guide* is a complete book about
|
|
|
|
|
editions that enumerates the differences between editions and explains how to
|
|
|
|
|
automatically upgrade your code to a new edition via `cargo fix`.
|
|
|
|
|
|