Skip to content

Commit 783b56b

Browse files
authored
Rollup merge of #93851 - cyqsimon:option-examples, r=scottmcm
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.
2 parents aff74a1 + f6f93fd commit 783b56b

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

library/core/src/option.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1207,13 +1207,25 @@ impl<T> Option<T> {
12071207
/// # Examples
12081208
///
12091209
/// ```
1210-
/// fn sq(x: u32) -> Option<u32> { Some(x * x) }
1211-
/// fn nope(_: u32) -> Option<u32> { None }
1210+
/// fn sq_then_to_string(x: u32) -> Option<String> {
1211+
/// x.checked_mul(x).map(|sq| sq.to_string())
1212+
/// }
1213+
///
1214+
/// assert_eq!(Some(2).and_then(sq_then_to_string), Some(4.to_string()));
1215+
/// assert_eq!(Some(1_000_000).and_then(sq_then_to_string), None); // overflowed!
1216+
/// assert_eq!(None.and_then(sq_then_to_string), None);
1217+
/// ```
1218+
///
1219+
/// Often used to chain fallible operations that may return [`None`].
1220+
///
1221+
/// ```
1222+
/// let arr_2d = [["A0", "A1"], ["B0", "B1"]];
1223+
///
1224+
/// let item_0_1 = arr_2d.get(0).and_then(|row| row.get(1));
1225+
/// assert_eq!(item_0_1, Some(&"A1"));
12121226
///
1213-
/// assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16));
1214-
/// assert_eq!(Some(2).and_then(sq).and_then(nope), None);
1215-
/// assert_eq!(Some(2).and_then(nope).and_then(sq), None);
1216-
/// assert_eq!(None.and_then(sq).and_then(sq), None);
1227+
/// let item_2_0 = arr_2d.get(2).and_then(|row| row.get(0));
1228+
/// assert_eq!(item_2_0, None);
12171229
/// ```
12181230
#[inline]
12191231
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/result.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -1281,16 +1281,28 @@ impl<T, E> Result<T, E> {
12811281
///
12821282
/// # Examples
12831283
///
1284-
/// Basic usage:
1284+
/// ```
1285+
/// fn sq_then_to_string(x: u32) -> Result<String, &'static str> {
1286+
/// x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed")
1287+
/// }
12851288
///
1289+
/// assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string()));
1290+
/// assert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed"));
1291+
/// assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number"));
12861292
/// ```
1287-
/// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
1288-
/// fn err(x: u32) -> Result<u32, u32> { Err(x) }
12891293
///
1290-
/// assert_eq!(Ok(2).and_then(sq).and_then(sq), Ok(16));
1291-
/// assert_eq!(Ok(2).and_then(sq).and_then(err), Err(4));
1292-
/// assert_eq!(Ok(2).and_then(err).and_then(sq), Err(2));
1293-
/// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3));
1294+
/// Often used to chain fallible operations that may return [`Err`].
1295+
///
1296+
/// ```
1297+
/// use std::{io::ErrorKind, path::Path};
1298+
///
1299+
/// // Note: on Windows "/" maps to "C:\"
1300+
/// let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified());
1301+
/// assert!(root_modified_time.is_ok());
1302+
///
1303+
/// let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified());
1304+
/// assert!(should_fail.is_err());
1305+
/// assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound);
12941306
/// ```
12951307
#[inline]
12961308
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)