]> git.lizzy.rs Git - rust.git/commitdiff
Expand docs on Iterator::intersperse
authorLukas Lueg <lukas.lueg@gmail.com>
Mon, 18 Jan 2021 19:40:25 +0000 (20:40 +0100)
committerLukas Lueg <lukas.lueg@gmail.com>
Thu, 21 Jan 2021 18:47:57 +0000 (19:47 +0100)
library/core/src/iter/adapters/intersperse.rs
library/core/src/iter/traits/iterator.rs

index 1d01e9b5fb7dc9533cf8eefbdf7699538ee84e09..4a40f8809aec7e43ce34a2176364d4274537a420 100644 (file)
@@ -151,12 +151,10 @@ fn intersperse_size_hint<I>(iter: &I, needs_sep: bool) -> (usize, Option<usize>)
 {
     let (lo, hi) = iter.size_hint();
     let next_is_elem = !needs_sep;
-    let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo);
-    let hi = match hi {
-        Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi),
-        None => None,
-    };
-    (lo, hi)
+    (
+        lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
+        hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
+    )
 }
 
 fn intersperse_fold<I, B, F, G>(
index 83d339d8f40a5664d97a93bca4ff222cfc871985..e3b2c394e544666efee17c3ee0b62339b8b9d8e5 100644 (file)
@@ -569,9 +569,10 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
         Zip::new(self, other.into_iter())
     }
 
-    /// Places a copy of `separator` between all elements.
+    /// Creates a new iterator which places a copy of `separator` between adjacent
+    /// items of the original iterator.
     ///
-    /// In case the separator does not implement [`Clone`] or needs to be
+    /// In case `separator` does not implement [`Clone`] or needs to be
     /// computed every time, use [`intersperse_with`].
     ///
     /// # Examples
@@ -581,6 +582,19 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
     /// ```
     /// #![feature(iter_intersperse)]
     ///
+    /// let mut a = [0, 1, 2].iter().intersperse(&100);
+    /// assert_eq!(a.next(), Some(&0));   // The first element from `a`.
+    /// assert_eq!(a.next(), Some(&100)); // The separator.
+    /// assert_eq!(a.next(), Some(&1));   // The next element from `a`.
+    /// assert_eq!(a.next(), Some(&100)); // The separator.
+    /// assert_eq!(a.next(), Some(&2));   // The last element from `a`.
+    /// assert_eq!(a.next(), None);       // The iterator is finished.
+    /// ```
+    ///
+    /// `intersperse` can be very useful to join an iterator's items using a common element:
+    /// ```
+    /// #![feature(iter_intersperse)]
+    ///
     /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
     /// assert_eq!(hello, "Hello World !");
     /// ```
@@ -597,7 +611,16 @@ fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
         Intersperse::new(self, separator)
     }
 
-    /// Places an element generated by `separator` between all elements.
+    /// Creates a new iterator which places an item generated by `separator`
+    /// between adjacent items of the original iterator.
+    ///
+    /// The closure will be called exactly once each time an item is placed
+    /// between two adjacent items from the underlying iterator; specifically,
+    /// the closure is not called if the underlying iterator yields less than
+    /// two items and after the last item is yielded.
+    ///
+    /// If the iterator's item implements [`Clone`], it may be easier to use
+    /// [`intersperse`].
     ///
     /// # Examples
     ///
@@ -606,14 +629,36 @@ fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
     /// ```
     /// #![feature(iter_intersperse)]
     ///
+    /// #[derive(PartialEq, Debug)]
+    /// struct NotClone(usize);
+    ///
+    /// let v = vec![NotClone(0), NotClone(1), NotClone(2)];
+    /// let mut it = v.into_iter().intersperse_with(|| NotClone(99));
+    ///
+    /// assert_eq!(it.next(), Some(NotClone(0)));  // The first element from `v`.
+    /// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
+    /// assert_eq!(it.next(), Some(NotClone(1)));  // The next element from `v`.
+    /// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
+    /// assert_eq!(it.next(), Some(NotClone(2)));  // The last element from from `v`.
+    /// assert_eq!(it.next(), None);               // The iterator is finished.
+    /// ```
+    ///
+    /// `intersperse_with` can be used in situations where the separator needs
+    /// to be computed:
+    /// ```
+    /// #![feature(iter_intersperse)]
+    ///
     /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
     ///
+    /// // The closure mutably borrows it's context to generate an item.
     /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
     /// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
     ///
     /// let result = src.intersperse_with(separator).collect::<String>();
     /// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!");
     /// ```
+    /// [`Clone`]: crate::clone::Clone
+    /// [`intersperse`]: Iterator::intersperse
     #[inline]
     #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
     fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>