Skip to content

Commit f90f0b3

Browse files
Rollup merge of #59362 - pnkfelix:demo-from-iterator-short-circuiting, r=Centril
Demo `FromIterator` short-circuiting while looking at a FIXME in `FromIterator for Option` and `FromIterator for Result`, I realized that the current documentation does not have example code showing exactly what is meant by "no further elements are taken." The code snippets provided here are meant to correct that.
2 parents ab4c5b3 + d5a61c0 commit f90f0b3

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/libcore/option.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,26 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
13151315
/// Since the last element is zero, it would underflow. Thus, the resulting
13161316
/// value is `None`.
13171317
///
1318+
/// Here is a variation on the previous example, showing that no
1319+
/// further elements are taken from `iter` after the first `None`.
1320+
///
1321+
/// ```
1322+
/// let items = vec![3_u16, 2, 1, 10];
1323+
///
1324+
/// let mut shared = 0;
1325+
///
1326+
/// let res: Option<Vec<u16>> = items
1327+
/// .iter()
1328+
/// .map(|x| shared += x; x.checked_sub(2))
1329+
/// .collect();
1330+
///
1331+
/// assert_eq!(res, None);
1332+
/// assert_eq!(shared, 6);
1333+
/// ```
1334+
///
1335+
/// Since the third element caused an underflow, no further elements were taken,
1336+
/// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
1337+
///
13181338
/// [`Iterator`]: ../iter/trait.Iterator.html
13191339
#[inline]
13201340
fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {

src/libcore/result.rs

+28
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,34 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
12021202
/// ).collect();
12031203
/// assert_eq!(res, Ok(vec![2, 3]));
12041204
/// ```
1205+
///
1206+
/// Here is another example that tries to subtract one from another list
1207+
/// of integers, this time checking for underflow:
1208+
///
1209+
/// ```
1210+
/// let v = vec![1, 2, 0];
1211+
/// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
1212+
/// x.checked_sub(1).ok_or("Underflow!")
1213+
/// ).collect();
1214+
/// assert_eq!(res, Err("Underflow!"));
1215+
/// ```
1216+
///
1217+
/// Here is a variation on the previous example, showing that no
1218+
/// further elements are taken from `iter` after the first `Err`.
1219+
///
1220+
/// ```
1221+
/// let v = vec![3, 2, 1, 10];
1222+
/// let mut shared = 0;
1223+
/// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
1224+
/// shared += x;
1225+
/// x.checked_sub(2).ok_or("Underflow!")
1226+
/// ).collect();
1227+
/// assert_eq!(res, Err("Underflow!"));
1228+
/// assert_eq!(shared, 6);
1229+
/// ```
1230+
///
1231+
/// Since the third element caused an underflow, no further elements were taken,
1232+
/// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
12051233
#[inline]
12061234
fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
12071235
// FIXME(#11084): This could be replaced with Iterator::scan when this

0 commit comments

Comments
 (0)