diff --git a/src/ch03-05-control-flow.md b/src/ch03-05-control-flow.md index 6bde6748fe..8259eddae2 100644 --- a/src/ch03-05-control-flow.md +++ b/src/ch03-05-control-flow.md @@ -242,16 +242,9 @@ can use it, as shown here: {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs}} ``` -Before the loop, we declare a variable named `counter` and initialize it to -`0`. Then, we declare a variable named `result` to hold the value returned from -the loop. On every iteration of the loop, we add `1` to the `counter` variable, -and then check whether the `counter` is equal to `10`. When it is, we use the -`break` keyword with the value `counter * 2`. After the loop, we use a -semicolon to end the statement that assigns the value to `result`. Finally, we -print the value in `result`, which in this case is `20`. - -You can also `return` from inside a loop. While `break` only exits the current -loop, `return` always exits the current function. +Before the loop, we declare a variable named counter and initialize it to 0. Then, we declare a variable named result to hold the value returned from the loop. On every iteration of the loop, we add 1 to the counter variable, and then check whether the counter is equal to 10. When it is, we use the break keyword with the value counter * 2, which exits the loop and supplies that value as the result of the loop expression. The break statement can be written with or without a trailing semicolon because it immediately transfers control flow out of the loop, so the semicolon does not affect the value being returned. After the loop, we use a semicolon to end the statement that assigns the value to result. Finally, we print the value in result, which in this case is 20. + +You can also return from inside a loop. While break only exits the current loop, return always exits the current function. diff --git a/src/ch08-03-hash-maps.md b/src/ch08-03-hash-maps.md index 696216245f..51037fc047 100644 --- a/src/ch08-03-hash-maps.md +++ b/src/ch08-03-hash-maps.md @@ -169,11 +169,11 @@ inserts the parameter as the new value for this key and returns a mutable reference to the new value. This technique is much cleaner than writing the logic ourselves and, in addition, plays more nicely with the borrow checker. -Running the code in Listing 8-24 will print `{"Yellow": 50, "Blue": 10}`. The -first call to `entry` will insert the key for the Yellow team with the value -`50` because the Yellow team doesn’t have a value already. The second call to -`entry` will not change the hash map, because the Blue team already has the -value `10`. +Running the code in Listing 8-24 will print `{"Blue": 10, "Yellow": 50}`. The +first call to `insert` will add the first value for the Blue team. Then the call +to `entry` will insert the key for the Yellow team with the value `50` because +the Yellow team doesn’t have a value already. The second call to `entry` will not +change the hashmap , because the Blue team already has the value `10`. #### Updating a Value Based on the Old Value diff --git a/src/ch19-01-all-the-places-for-patterns.md b/src/ch19-01-all-the-places-for-patterns.md index 1a6d21eb54..97e6841853 100644 --- a/src/ch19-01-all-the-places-for-patterns.md +++ b/src/ch19-01-all-the-places-for-patterns.md @@ -159,13 +159,22 @@ This conditional structure lets us support complex requirements. With the hardcoded values we have here, this example will print `Using purple as the background color`. -You can see that `if let` can also introduce new variables that shadow existing -variables in the same way that `match` arms can: The line `if let Ok(age) = age` -introduces a new `age` variable that contains the value inside the `Ok` variant, -shadowing the existing `age` variable. This means we need to place the `if age > -30` condition within that block: We can’t combine these two conditions into `if -let Ok(age) = age && age > 30`. The new `age` we want to compare to 30 isn’t -valid until the new scope starts with the curly bracket. +You can see that `if let` can introduce new variables that shadow existing +variables in the same way that `match` arms can. In the line `if let Ok(age) = age`, +a new `age` variable is introduced that contains the value inside the `Ok` +variant, shadowing the existing age variable of type Result. +This shadowing is important to understand because the newly bound variable +is only valid after the pattern has successfully matched, and using it outside +of its well-defined scope would be unsound. For this reason, older versions of +Rust required any additional conditions, such as `age > 30`, to be placed inside +the block, where the new binding was guaranteed to exist. However, modern Rust +supports `if-let` chains, which allow writing `if let Ok(age) = age && age > 30`. +This works because the compiler now understands the left-to-right, short-circuiting +semantics of the condition: the pattern match must succeed before the new `age` +binding becomes available to the `age > 30` check. Even with this newer syntax, +the underlying rule remains the same—bindings introduced by patterns are only valid +once the pattern has matched, and Rust enforces this strictly to avoid accidental +misuse caused by shadowing. The downside of using `if let` expressions is that the compiler doesn’t check for exhaustiveness, whereas with `match` expressions it does. If we omitted the