diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-03-26 09:05:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-26 09:05:47 +0100 |
| commit | 0616b73c2fbe019e3c9273ab10cdf2ef16a78df1 (patch) | |
| tree | bf898498d8ae94f6e6e21a9b517ec7790d174254 | |
| parent | e132e43e85fed008be31d813f13c041fc8b0551b (diff) | |
| parent | 0e83e96852e9aacde2bf633bb17b293910073812 (diff) | |
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.
| -rw-r--r-- | src/libcore/option.rs | 20 | ||||
| -rw-r--r-- | src/libcore/result.rs | 28 |
2 files changed, 48 insertions, 0 deletions
diff --git a/src/libcore/option.rs b/src/libcore/option.rs index dfc388409a8..3da92c0a05a 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1315,6 +1315,26 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { /// Since the last element is zero, it would underflow. Thus, the resulting /// value is `None`. /// + /// Here is a variation on the previous example, showing that no + /// further elements are taken from `iter` after the first `None`. + /// + /// ``` + /// let items = vec![3_u16, 2, 1, 10]; + /// + /// let mut shared = 0; + /// + /// let res: Option<Vec<u16>> = items + /// .iter() + /// .map(|x| { shared += x; x.checked_sub(2) }) + /// .collect(); + /// + /// assert_eq!(res, None); + /// assert_eq!(shared, 6); + /// ``` + /// + /// Since the third element caused an underflow, no further elements were taken, + /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. + /// /// [`Iterator`]: ../iter/trait.Iterator.html #[inline] fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 967f7e3e2fe..9b7b8368986 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1202,6 +1202,34 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { /// ).collect(); /// assert_eq!(res, Ok(vec![2, 3])); /// ``` + /// + /// Here is another example that tries to subtract one from another list + /// of integers, this time checking for underflow: + /// + /// ``` + /// let v = vec![1, 2, 0]; + /// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| + /// x.checked_sub(1).ok_or("Underflow!") + /// ).collect(); + /// assert_eq!(res, Err("Underflow!")); + /// ``` + /// + /// Here is a variation on the previous example, showing that no + /// further elements are taken from `iter` after the first `Err`. + /// + /// ``` + /// let v = vec![3, 2, 1, 10]; + /// let mut shared = 0; + /// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| { + /// shared += x; + /// x.checked_sub(2).ok_or("Underflow!") + /// }).collect(); + /// assert_eq!(res, Err("Underflow!")); + /// assert_eq!(shared, 6); + /// ``` + /// + /// Since the third element caused an underflow, no further elements were taken, + /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. #[inline] fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> { // FIXME(#11084): This could be replaced with Iterator::scan when this |
