summaryrefslogtreecommitdiffstats
path: root/src/doc/book/nostarch/appendix.md
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/doc/book/nostarch/appendix.md
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/doc/book/nostarch/appendix.md')
-rw-r--r--src/doc/book/nostarch/appendix.md765
1 files changed, 765 insertions, 0 deletions
diff --git a/src/doc/book/nostarch/appendix.md b/src/doc/book/nostarch/appendix.md
new file mode 100644
index 000000000..1722a9345
--- /dev/null
+++ b/src/doc/book/nostarch/appendix.md
@@ -0,0 +1,765 @@
+<!-- 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
+
+The following list contains keywords that are reserved for current or future
+use by the Rust language. As such, they cannot be used as identifiers (except
+as raw identifiers as we’ll discuss in the “Raw Identifiers” section).
+Identifiers are names of functions, variables, parameters, struct fields,
+modules, crates, constants, macros, static values, attributes, types, traits,
+or lifetimes.
+
+### Keywords Currently in Use
+
+The following is a list of keywords currently in use, with their functionality
+described.
+
+* `as` - perform primitive casting, disambiguate the specific trait containing
+ an item, or rename items in `use` statements
+
+<!-- `extern crate` is a bit old. Not sure if it needs a mention
+/JT -->
+<!-- good call, took it out /Carol -->
+
+* `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
+<!-- these days `crate` is mostly just used as part of the module path
+/JT -->
+<!-- fixed! /Carol -->
+
+* `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
+<!-- `extern crate` is a bit out of date
+/JT -->
+<!-- fixed! /Carol -->
+
+* `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
+ higher-ranked lifetime
+* `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 only a keyword 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
+
+### Keywords Reserved for Future Use
+
+The following keywords do not yet have any functionality but are reserved by
+Rust for potential future use.
+
+* `abstract`
+* `become`
+* `box`
+* `do`
+* `final`
+* `macro`
+* `override`
+* `priv`
+* `try`
+* `typeof`
+* `unsized`
+* `virtual`
+* `yield`
+
+### Raw Identifiers
+
+*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#`.
+
+For example, `match` is a keyword. If you try to compile the following function
+that uses `match` as its name:
+
+Filename: src/main.rs
+
+```
+fn match(needle: &str, haystack: &str) -> bool {
+ haystack.contains(needle)
+}
+```
+
+you’ll get this error:
+
+```
+error: expected identifier, found keyword `match`
+ --> src/main.rs:4:4
+ |
+4 | fn match(needle: &str, haystack: &str) -> bool {
+ | ^^^^^ expected identifier, found keyword
+```
+
+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:
+
+Filename: src/main.rs
+
+```
+fn r#match(needle: &str, haystack: &str) -> bool {
+ haystack.contains(needle)
+}
+
+fn main() {
+ assert!(r#match("foo", "foobar"));
+}
+```
+
+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`.
+
+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
+edition. If you depend on a library that’s 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 2018 edition code. See Appendix E
+for more information on editions.
+
+## Appendix B: Operators and Symbols
+
+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.
+
+### Operators
+
+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.
+
+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`, <code>&vert;...&vert; -> type</code> | 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` |
+| <code>&vert;</code> | <code>pat &vert; pat</code> | Pattern alternatives | |
+| <code>&vert;</code> | <code>expr &vert; expr</code> | Bitwise OR | `BitOr` |
+| <code>&vert;=</code> | <code>var &vert;= expr</code> | Bitwise OR and assignment | `BitOrAssign` |
+| <code>&vert;&vert;</code> | <code>expr &vert;&vert; expr</code> | Short-circuiting logical OR | |
+| `?` | `expr?` | Error propagation | |
+
+### Non-operator Symbols
+
+The following list contains all symbols that don’t function as operators;
+that is, they don’t behave like a function or method call.
+
+Table B-2 shows symbols that appear on their own and are valid in a variety of
+locations.
+
+Table B-2: Stand-Alone Syntax
+
+| Symbol | Explanation |
+|--------|-------------|
+| `'ident` | Named lifetime or loop label |
+| `...u8`, `...i32`, `...f64`, `...usize`, etc. | Numeric literal of specific type |
+| `"..."` | String literal |
+| `r"..."`, `r#"..."#`, `r##"..."##`, etc. | Raw string literal, escape characters not processed |
+| `b"..."` | Byte string literal; constructs an array of bytes instead of a string |
+| `br"..."`, `br#"..."#`, `br##"..."##`, etc. | Raw byte string literal, combination of raw and byte string literal |
+| `'...'` | Character literal |
+| `b'...'` | ASCII byte literal |
+| <code>&vert;...&vert; expr</code> | 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 (i.e., an explicitly absolute path) |
+| `self::path` | Path relative to the current module (i.e., 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 (e.g., `<&T>::...`, `<[T]>::...`, etc.) |
+| `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.
+
+Table B-4: Generics
+
+| Symbol | Explanation |
+|--------|-------------|
+| `path<...>` | Specifies parameters to generic type in a type (e.g., `Vec<u8>`) |
+| `path::<...>`, `method::<...>` | Specifies parameters to generic type, function, or method in an expression; often referred to as turbofish (e.g., `"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 (e.g., `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.
+
+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`, etc. | Tuple indexing |
+
+Table B-9 shows the contexts in which curly braces 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” |
+
+## 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
+
+If you want different behavior from that provided by the `derive` attribute,
+consult the standard library documentation for each trait for details of how to
+manually implement them.
+
+These 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.
+
+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
+traits you can use `derive` with truly open-ended. Implementing `derive`
+involves using a procedural macro, which is covered in the
+“Macros” section of Chapter 19.
+
+### `Debug` for Programmer Output
+
+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.
+
+The `Debug` trait is required, for example, in 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.
+
+### `PartialEq` and `Eq` for Equality Comparisons
+
+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
+implement `PartialEq` can implement `Eq`. One example of this is floating point
+number types: the implementation of floating point numbers states that two
+instances of the not-a-number (`NaN`) value are not equal to each other.
+
+An example of when `Eq` is required is for keys in a `HashMap<K, V>` so the
+`HashMap<K, V>` can tell whether two keys are the same.
+
+### `PartialOrd` and `Ord` for Ordering Comparisons
+
+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
+point value. Calling `partial_cmp` with any floating point number and the `NaN`
+floating point value will return `None`.
+
+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.
+
+### `Clone` and `Copy` for Duplicating Values
+
+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
+data. See the “Ways Variables and Data Interact: Clone” section in Chapter 4
+for more information on `Clone`.
+
+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
+`clone` on each item. Thus, the type stored in the slice must implement `Clone`.
+
+The `Copy` trait allows you to duplicate a value by only copying bits stored on
+the stack; no arbitrary code is necessary. See the “Stack-Only Data: Copy”
+section in Chapter 4 for more information on `Copy`.
+
+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
+implements `Copy` must also implement `Clone`, because a type that implements
+`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.
+
+### `Hash` for Mapping a Value to a Value of Fixed Size
+
+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.
+
+### `Default` for Default Values
+
+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
+update syntax discussed in the “Creating Instances From Other Instances With
+Struct Update Syntax” section in Chapter 5. 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
+`..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>`.
+
+## Appendix D - Useful Development Tools
+
+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.
+
+### Automatic Formatting with `rustfmt`
+
+The `rustfmt` tool reformats your code according to the community code style.
+Many collaborative projects use `rustfmt` to prevent arguments about which
+style to use when writing Rust: everyone formats their code using the tool.
+
+To install `rustfmt`, enter the following:
+
+```
+$ rustup component add rustfmt
+```
+
+This command gives you `rustfmt` and `cargo-fmt`, similar to how Rust gives you
+both `rustc` and `cargo`. To format any Cargo project, enter the following:
+
+```
+$ 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*.
+
+
+### Fix Your Code with `rustfix`
+
+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. It’s likely you’ve seen compiler warnings before. For example,
+consider this code:
+
+Filename: src/main.rs
+
+```
+fn do_something() {}
+
+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
+
+ 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.
+
+### More Lints with Clippy
+
+The Clippy tool is a collection of lints to analyze your code so you can catch
+common mistakes and improve your Rust code.
+
+To install Clippy, enter the following:
+
+```
+$ rustup component add clippy
+```
+
+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:
+
+```
+error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly
+ --> src/main.rs:2:13
+ |
+2 | let x = 3.1415;
+ | ^^^^^^
+ |
+ = note: #[deny(clippy::approx_constant)] on by default
+ = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/master/index.html#approx_constant
+```
+
+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.
+
+The following code doesn’t result in any errors or warnings from Clippy:
+
+Filename: src/main.rs
+
+```
+fn main() {
+ let x = std::f64::consts::PI;
+ let r = 8.0;
+ println!("the area of the circle is {}", x * r * r);
+}
+```
+
+For more information on Clippy, see its documentation at *https://github.com/rust-lang/rust-clippy*.
+
+### IDE Integration Using `rust-analyzer`
+
+To help IDE integration, the Rust community recommends using `rust-analyzer`.
+This tool is a set of compiler-centric utilities that speaks the 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
+*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
+abilities such as autocompletion, jump to definition, and inline errors.
+
+## Appendix E - Editions
+
+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
+ an easy-to-understand package.
+* For non-users, a new edition signals that some major advancements have
+ landed, which might make Rust worth another look.
+* For those developing Rust, a new edition provides a rallying point for the
+ project as a whole.
+
+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.
+
+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`.