From e516e369cf192fb71d0e7f5b1bcd9f58729b5a89 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Thu, 30 Jan 2025 09:35:30 -0800 Subject: [PATCH 1/3] Remove nesting from `let else` example --- .../let-control-flow/let-else.md | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/pattern-matching/let-control-flow/let-else.md b/src/pattern-matching/let-control-flow/let-else.md index aceef48e5f8f..d794b80032a4 100644 --- a/src/pattern-matching/let-control-flow/let-else.md +++ b/src/pattern-matching/let-control-flow/let-else.md @@ -7,19 +7,19 @@ off the end of the block). ```rust,editable fn hex_or_die_trying(maybe_string: Option) -> Result { - // TODO: The structure of this code is difficult to follow -- rewrite it with let-else! - if let Some(s) = maybe_string { - if let Some(first_byte_char) = s.chars().next() { - if let Some(digit) = first_byte_char.to_digit(16) { - Ok(digit) - } else { - Err(String::from("not a hex digit")) - } - } else { - Err(String::from("got empty string")) - } - } else { - Err(String::from("got None")) + let s = match maybe_string { + Some(s) => s, + None => return Err(String::from("got None")), + }; + + let first_byte_char = match s.chars().next() { + Some(first) => first, + None => return Err(String::from("got empty string")), + }; + + match first_byte_char.to_digit(16) { + Some(digit) => Ok(digit), + None => Err(String::from("not a hex digit")), } } @@ -29,11 +29,6 @@ fn main() { ```
- -`if-let`s can pile up, as shown. The `let-else` construct supports flattening -this nested code. Rewrite the awkward version for students, so they can see the -transformation. - The rewritten version is: ```rust From b6078009e481cb1fc962fa4a6bf1b0a8c5ca2a5b Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Thu, 30 Jan 2025 09:42:33 -0800 Subject: [PATCH 2/3] Add speaker notes about `?` --- src/pattern-matching/let-control-flow/let-else.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pattern-matching/let-control-flow/let-else.md b/src/pattern-matching/let-control-flow/let-else.md index d794b80032a4..db046818edbc 100644 --- a/src/pattern-matching/let-control-flow/let-else.md +++ b/src/pattern-matching/let-control-flow/let-else.md @@ -49,4 +49,12 @@ fn hex_or_die_trying(maybe_string: Option) -> Result { } ``` +## More to Explore + +- This early return-based control flow is common in Rust error handling code, + where you try to get a value out of a `Result`, returning an error if the + `Result` was `Err`. +- If students ask, you can also demonstrate how real error handling code would + be written with `?`. +
From 7b9e5ed1b4f406c8726140c6f82f5ca38278ca90 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Fri, 7 Feb 2025 14:35:15 -0800 Subject: [PATCH 3/3] Use `if let` instead of `match` --- .../let-control-flow/let-else.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/pattern-matching/let-control-flow/let-else.md b/src/pattern-matching/let-control-flow/let-else.md index db046818edbc..f405c6816986 100644 --- a/src/pattern-matching/let-control-flow/let-else.md +++ b/src/pattern-matching/let-control-flow/let-else.md @@ -7,20 +7,25 @@ off the end of the block). ```rust,editable fn hex_or_die_trying(maybe_string: Option) -> Result { - let s = match maybe_string { - Some(s) => s, - None => return Err(String::from("got None")), + let s = if let Some(s) = maybe_string { + s + } else { + return Err(String::from("got None")); + }; + + let first_byte_char = if let Some(first) = s.chars().next() { + first + } else { + return Err(String::from("got empty string")); }; - let first_byte_char = match s.chars().next() { - Some(first) => first, - None => return Err(String::from("got empty string")), + let digit = if let Some(digit) = first_byte_char.to_digit(16) { + digit + } else { + return Err(String::from("not a hex digit")); }; - match first_byte_char.to_digit(16) { - Some(digit) => Ok(digit), - None => Err(String::from("not a hex digit")), - } + Ok(digit) } fn main() {