Skip to content

Commit 226fe55

Browse files
authored
Rollup merge of #81173 - lukaslueg:intersperse_docs, r=m-ou-se
Expand docs on Iterator::intersperse Unstable feature in #79524. This expands on the docs to bring them more in line with how other methods of `Iterator` are demonstrated.
2 parents 98c0364 + c61785e commit 226fe55

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
@@ -567,9 +567,10 @@ pub trait Iterator {
567567
Zip::new(self, other.into_iter())
568568
}
569569

570-
/// Places a copy of `separator` between all elements.
570+
/// Creates a new iterator which places a copy of `separator` between adjacent
571+
/// items of the original iterator.
571572
///
572-
/// In case the separator does not implement [`Clone`] or needs to be
573+
/// In case `separator` does not implement [`Clone`] or needs to be
573574
/// computed every time, use [`intersperse_with`].
574575
///
575576
/// # Examples
@@ -579,6 +580,19 @@ pub trait Iterator {
579580
/// ```
580581
/// #![feature(iter_intersperse)]
581582
///
583+
/// let mut a = [0, 1, 2].iter().intersperse(&100);
584+
/// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
585+
/// assert_eq!(a.next(), Some(&100)); // The separator.
586+
/// assert_eq!(a.next(), Some(&1)); // The next element from `a`.
587+
/// assert_eq!(a.next(), Some(&100)); // The separator.
588+
/// assert_eq!(a.next(), Some(&2)); // The last element from `a`.
589+
/// assert_eq!(a.next(), None); // The iterator is finished.
590+
/// ```
591+
///
592+
/// `intersperse` can be very useful to join an iterator's items using a common element:
593+
/// ```
594+
/// #![feature(iter_intersperse)]
595+
///
582596
/// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
583597
/// assert_eq!(hello, "Hello World !");
584598
/// ```
@@ -595,7 +609,16 @@ pub trait Iterator {
595609
Intersperse::new(self, separator)
596610
}
597611

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

0 commit comments

Comments
 (0)