Skip to content

Commit 653bcc8

Browse files
committed
Expand docs on Iterator::intersperse
1 parent 5e91c4e commit 653bcc8

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

library/core/src/iter/adapters/intersperse.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,10 @@ where
151151
{
152152
let (lo, hi) = iter.size_hint();
153153
let next_is_elem = !needs_sep;
154-
let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo);
155-
let hi = match hi {
156-
Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi),
157-
None => None,
158-
};
159-
(lo, hi)
154+
(
155+
lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
156+
hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
157+
)
160158
}
161159

162160
fn intersperse_fold<I, B, F, G>(

library/core/src/iter/traits/iterator.rs

+48-3
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,10 @@ pub trait Iterator {
569569
Zip::new(self, other.into_iter())
570570
}
571571

572-
/// Places a copy of `separator` between all elements.
572+
/// Creates a new iterator which places a copy of `separator` between adjacent
573+
/// items of the original iterator.
573574
///
574-
/// In case the separator does not implement [`Clone`] or needs to be
575+
/// In case `separator` does not implement [`Clone`] or needs to be
575576
/// computed every time, use [`intersperse_with`].
576577
///
577578
/// # Examples
@@ -581,6 +582,19 @@ pub trait Iterator {
581582
/// ```
582583
/// #![feature(iter_intersperse)]
583584
///
585+
/// let mut a = [0, 1, 2].iter().intersperse(&100);
586+
/// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
587+
/// assert_eq!(a.next(), Some(&100)); // The separator.
588+
/// assert_eq!(a.next(), Some(&1)); // The next element from `a`.
589+
/// assert_eq!(a.next(), Some(&100)); // The separator.
590+
/// assert_eq!(a.next(), Some(&2)); // The last element from `a`.
591+
/// assert_eq!(a.next(), None); // The iterator is finished.
592+
/// ```
593+
///
594+
/// `intersperse` can be very useful to join an iterator's items using a common element:
595+
/// ```
596+
/// #![feature(iter_intersperse)]
597+
///
584598
/// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
585599
/// assert_eq!(hello, "Hello World !");
586600
/// ```
@@ -597,7 +611,16 @@ pub trait Iterator {
597611
Intersperse::new(self, separator)
598612
}
599613

600-
/// Places an element generated by `separator` between all elements.
614+
/// Creates a new iterator which places an item generated by `separator`
615+
/// between adjacent items of the original iterator.
616+
///
617+
/// The closure will be called exactly once each time an item is placed
618+
/// between two adjacent items from the underlying iterator; specifically,
619+
/// the closure is not called if the underlying iterator yields less than
620+
/// two items and after the last item is yielded.
621+
///
622+
/// If the iterator's item implements [`Clone`], it may be easier to use
623+
/// [`intersperse`].
601624
///
602625
/// # Examples
603626
///
@@ -606,14 +629,36 @@ pub trait Iterator {
606629
/// ```
607630
/// #![feature(iter_intersperse)]
608631
///
632+
/// #[derive(PartialEq, Debug)]
633+
/// struct NotClone(usize);
634+
///
635+
/// let v = vec![NotClone(0), NotClone(1), NotClone(2)];
636+
/// let mut it = v.into_iter().intersperse_with(|| NotClone(99));
637+
///
638+
/// assert_eq!(it.next(), Some(NotClone(0))); // The first element from `v`.
639+
/// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
640+
/// assert_eq!(it.next(), Some(NotClone(1))); // The next element from `v`.
641+
/// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
642+
/// assert_eq!(it.next(), Some(NotClone(2))); // The last element from from `v`.
643+
/// assert_eq!(it.next(), None); // The iterator is finished.
644+
/// ```
645+
///
646+
/// `intersperse_with` can be used in situations where the separator needs
647+
/// to be computed:
648+
/// ```
649+
/// #![feature(iter_intersperse)]
650+
///
609651
/// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
610652
///
653+
/// // The closure mutably borrows it's context to generate an item.
611654
/// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
612655
/// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
613656
///
614657
/// let result = src.intersperse_with(separator).collect::<String>();
615658
/// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!");
616659
/// ```
660+
/// [`Clone`]: crate::clone::Clone
661+
/// [`intersperse`]: Iterator::intersperse
617662
#[inline]
618663
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
619664
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>

0 commit comments

Comments
 (0)