Skip to content

Commit

Permalink
Rollup merge of #93851 - cyqsimon:option-examples, r=scottmcm
Browse files Browse the repository at this point in the history
More practical examples for `Option::and_then` & `Result::and_then`

To be blatantly honest, I think the current example given for `Option::and_then` is objectively terrible. (No offence to whoever wrote them initially.)

```rust
fn sq(x: u32) -> Option<u32> { Some(x * x) }
fn nope(_: u32) -> Option<u32> { None }

assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16));
assert_eq!(Some(2).and_then(sq).and_then(nope), None);
assert_eq!(Some(2).and_then(nope).and_then(sq), None);
assert_eq!(None.and_then(sq).and_then(sq), None);
```

Current example:
 - does not demonstrate that `and_then` converts `Option<T>` to `Option<U>`
 - is far removed from any realistic code
 - generally just causes more confusion than it helps

So I replaced them with two blocks:
 - the first one shows basic usage (including the type conversion)
 - the second one shows an example of typical usage

Same thing with `Result::and_then`.

Hopefully this helps with clarity.
  • Loading branch information
matthiaskrgr authored Feb 13, 2022
2 parents aff74a1 + f6f93fd commit 783b56b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
24 changes: 18 additions & 6 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,13 +1207,25 @@ impl<T> Option<T> {
/// # Examples
///
/// ```
/// fn sq(x: u32) -> Option<u32> { Some(x * x) }
/// fn nope(_: u32) -> Option<u32> { None }
/// fn sq_then_to_string(x: u32) -> Option<String> {
/// x.checked_mul(x).map(|sq| sq.to_string())
/// }
///
/// assert_eq!(Some(2).and_then(sq_then_to_string), Some(4.to_string()));
/// assert_eq!(Some(1_000_000).and_then(sq_then_to_string), None); // overflowed!
/// assert_eq!(None.and_then(sq_then_to_string), None);
/// ```
///
/// Often used to chain fallible operations that may return [`None`].
///
/// ```
/// let arr_2d = [["A0", "A1"], ["B0", "B1"]];
///
/// let item_0_1 = arr_2d.get(0).and_then(|row| row.get(1));
/// assert_eq!(item_0_1, Some(&"A1"));
///
/// assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16));
/// assert_eq!(Some(2).and_then(sq).and_then(nope), None);
/// assert_eq!(Some(2).and_then(nope).and_then(sq), None);
/// assert_eq!(None.and_then(sq).and_then(sq), None);
/// let item_2_0 = arr_2d.get(2).and_then(|row| row.get(0));
/// assert_eq!(item_2_0, None);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
26 changes: 19 additions & 7 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1281,16 +1281,28 @@ impl<T, E> Result<T, E> {
///
/// # Examples
///
/// Basic usage:
/// ```
/// fn sq_then_to_string(x: u32) -> Result<String, &'static str> {
/// x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed")
/// }
///
/// assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string()));
/// assert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed"));
/// assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number"));
/// ```
/// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
/// fn err(x: u32) -> Result<u32, u32> { Err(x) }
///
/// assert_eq!(Ok(2).and_then(sq).and_then(sq), Ok(16));
/// assert_eq!(Ok(2).and_then(sq).and_then(err), Err(4));
/// assert_eq!(Ok(2).and_then(err).and_then(sq), Err(2));
/// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3));
/// Often used to chain fallible operations that may return [`Err`].
///
/// ```
/// use std::{io::ErrorKind, path::Path};
///
/// // Note: on Windows "/" maps to "C:\"
/// let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified());
/// assert!(root_modified_time.is_ok());
///
/// let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified());
/// assert!(should_fail.is_err());
/// assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down

0 comments on commit 783b56b

Please sign in to comment.