From c76f1b4d011fe59fc4f5e6f258070fc40d9921e4 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Wed, 25 May 2022 20:40:36 -0400 Subject: [PATCH] Propagate tech review edits to ch06 src --- .../no-listing-06-option-examples/src/main.rs | 2 +- src/ch06-00-enums.md | 4 -- src/ch06-01-defining-an-enum.md | 37 +++++++++++-------- src/ch06-02-match.md | 37 ++++++++++--------- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs index 9de5791b41..be552bfa53 100644 --- a/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs @@ -1,7 +1,7 @@ fn main() { // ANCHOR: here let some_number = Some(5); - let some_string = Some("a string"); + let some_char = Some('e'); let absent_number: Option = None; // ANCHOR_END: here diff --git a/src/ch06-00-enums.md b/src/ch06-00-enums.md index 7fdfc2ccbc..e207aa7bd0 100644 --- a/src/ch06-00-enums.md +++ b/src/ch06-00-enums.md @@ -9,7 +9,3 @@ how pattern matching in the `match` expression makes it easy to run different code for different values of an enum. Finally, we’ll cover how the `if let` construct is another convenient and concise idiom available to handle enums in your code. - -Enums are a feature in many languages, but their capabilities differ in each -language. Rust’s enums are most similar to *algebraic data types* in functional -languages, such as F#, OCaml, and Haskell. diff --git a/src/ch06-01-defining-an-enum.md b/src/ch06-01-defining-an-enum.md index 33bf8eaa26..cb5d73097b 100644 --- a/src/ch06-01-defining-an-enum.md +++ b/src/ch06-01-defining-an-enum.md @@ -1,12 +1,17 @@ ## Defining an Enum -Enums are a way of defining custom data types in a different way than you do -with structs. Let’s look at a situation we might want to express in code and -see why enums are useful and more appropriate than structs in this case. Say we -need to work with IP addresses. Currently, two major standards are used for IP -addresses: version four and version six. Because these are the only -possibilities for an IP address that our program will come across, we can -*enumerate* all possible variants, which is where enumeration gets its name. +Where structs give you a way of grouping together related fields and data, like +a `Rectangle` with its `width` and `height`, enums give you a way of saying a +value is one of a possible set of values. For example, we may want to say that +`Rectangle` is one of a set of possible shapes that also includes `Circle` and +`Triangle`. To do this, Rust allows us to encode these possibilities as an enum. + +Let’s look at a situation we might want to express in code and see why enums +are useful and more appropriate than structs in this case. Say we need to work +with IP addresses. Currently, two major standards are used for IP addresses: +version four and version six. Because these are the only possibilities for an +IP address that our program will come across, we can *enumerate* all possible +variants, which is where enumeration gets its name. Any IP address can be either a version four or a version six address, but not both at the same time. That property of IP addresses makes the enum data @@ -183,12 +188,14 @@ useful: `Option`. This section explores a case study of `Option`, which is another enum defined by the standard library. The `Option` type encodes the very common scenario in -which a value could be something or it could be nothing. For example, if you -request the first of a list containing items, you would get a value. If you -request the first item of an empty list, you would get nothing. Expressing this -concept in terms of the type system means the compiler can check whether you’ve -handled all the cases you should be handling; this functionality can prevent -bugs that are extremely common in other programming languages. +which a value could be something or it could be nothing. + +For example, if you request the first of a list containing items, you would get +a value. If you request the first item of an empty list, you would get nothing. +Expressing this concept in terms of the type system means the compiler can +check whether you’ve handled all the cases you should be handling; this +functionality can prevent bugs that are extremely common in other programming +languages. Programming language design is often thought of in terms of which features you include, but the features you exclude are important too. Rust doesn’t have the @@ -246,8 +253,8 @@ types and string types: {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs:here}} ``` -The type of `some_number` is `Option`. The type of `some_string` is -`Option<&str>`, which is a different type. Rust can infer these types because +The type of `some_number` is `Option`. The type of `some_char` is +`Option`, which is a different type. Rust can infer these types because we’ve specified a value inside the `Some` variant. For `absent_number`, Rust requires us to annotate the overall `Option` type: the compiler can’t infer the type that the corresponding `Some` variant will hold by looking only at a diff --git a/src/ch06-02-match.md b/src/ch06-02-match.md index aafe661f1f..a249368294 100644 --- a/src/ch06-02-match.md +++ b/src/ch06-02-match.md @@ -14,6 +14,7 @@ down a track with variously sized holes along it, and each coin falls through the first hole it encounters that it fits into. In the same way, values go through each pattern in a `match`, and at the first pattern the value “fits,” the value falls into the associated code block to be used during execution. + Speaking of coins, let’s use them as an example using `match`! We can write a function that takes an unknown United States coin and, in a similar way as the counting machine, determines which coin it is and return its value in cents, as @@ -50,9 +51,10 @@ entire `match` expression. We don’t typically use curly brackets if the match arm code is short, as it is in Listing 6-3 where each arm just returns a value. If you want to run multiple -lines of code in a match arm, you must use curly brackets. For example, the -following code prints “Lucky penny!” every time the method is called with a -`Coin::Penny`, but still returns the last value of the block, `1`: +lines of code in a match arm, you must use curly brackets, and the comma +following the arm is then optional. For example, the following code prints +“Lucky penny!” every time the method is called with a `Coin::Penny`, but still +returns the last value of the block, `1`: ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs:here}} @@ -161,8 +163,9 @@ consistently a user favorite. ### Matches Are Exhaustive -There’s one other aspect of `match` we need to discuss. Consider this version -of our `plus_one` function that has a bug and won’t compile: +There’s one other aspect of `match` we need to discuss: the arms’ patterns must +cover all possibilities. Consider this version of our `plus_one` function, +which has a bug and won’t compile: ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs:here}} @@ -208,17 +211,17 @@ This code compiles, even though we haven’t listed all the possible values a `u8` can have, because the last pattern will match all values not specifically listed. This catch-all pattern meets the requirement that `match` must be exhaustive. Note that we have to put the catch-all arm last because the -patterns are evaluated in order. Rust will warn us if we add arms after a -catch-all because those later arms would never match! +patterns are evaluated in order. If we put the catch-all arm earlier, the other +arms would never run, so Rust will warn us if we add arms after a catch-all! -Rust also has a pattern we can use when we don’t want to use the value in the -catch-all pattern: `_`, which is a special pattern that matches any value and -does not bind to that value. This tells Rust we aren’t going to use the value, -so Rust won’t warn us about an unused variable. +Rust also has a pattern we can use when we want a catch-all but don’t want to +*use* the value in the catch-all pattern: `_` is a special pattern that matches +any value and does not bind to that value. This tells Rust we aren’t going to +use the value, so Rust won’t warn us about an unused variable. -Let’s change the rules of the game to be that if you roll anything other than -a 3 or a 7, you must roll again. We don’t need to use the value in that case, -so we can change our code to use `_` instead of the variable named `other`: +Let’s change the rules of the game: now, if you roll anything other than a 3 or +a 7, you must roll again. We no longer need to use the catch-all value, so we +can change our code to use `_` instead of the variable named `other`: ```rust {{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs:here}} @@ -227,9 +230,9 @@ so we can change our code to use `_` instead of the variable named `other`: This example also meets the exhaustiveness requirement because we’re explicitly ignoring all other values in the last arm; we haven’t forgotten anything. -If we change the rules of the game one more time, so that nothing else happens -on your turn if you roll anything other than a 3 or a 7, we can express that -by using the unit value (the empty tuple type we mentioned in [“The Tuple +Finally, we’ll change the rules of the game one more time, so that nothing else +happens on your turn if you roll anything other than a 3 or a 7. We can express +that by using the unit value (the empty tuple type we mentioned in [“The Tuple Type”][tuples] section) as the code that goes with the `_` arm: ```rust