Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions src/ch03-05-control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<!-- Old headings. Do not remove or links may break. -->
<a id="loop-labels-to-disambiguate-between-multiple-loops"></a>
Expand Down
10 changes: 5 additions & 5 deletions src/ch08-03-hash-maps.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
23 changes: 16 additions & 7 deletions src/ch19-01-all-the-places-for-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8, _>.
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
Expand Down
Loading