From 9d663a3e4a85be4c45194cd1c987dd77dee45ab7 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 17 Nov 2015 12:42:09 -0500 Subject: [PATCH] More docs for FromIterator And modifying IntoIterator for consisntency with it. Part of #29360 --- src/libcore/iter.rs | 148 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 132 insertions(+), 16 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 8558927e4acae..020f7e37a4a1d 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2375,32 +2375,118 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { } /// Conversion from an `Iterator`. +/// +/// By implementing `FromIterator` for a type, you define how it will be +/// created from an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// `FromIterator`'s [`from_iter()`] is rarely called explicitly, and is instead +/// used through [`Iterator`]'s [`collect()`] method. See [`collect()`]'s +/// documentation for more examples. +/// +/// [`from_iter()`]: #tymethod.from_iter +/// [`Iterator`]: trait.Iterator.html +/// [`collect()`]: trait.Iterator.html#method.collect +/// +/// See also: [`IntoIterator`]. +/// +/// [`IntoIterator`]: trait.IntoIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v = Vec::from_iter(five_fives); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Using [`collect()`] to implicitly use `FromIterator`: +/// +/// ``` +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v: Vec = five_fives.collect(); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Implementing `FromIterator` for your type: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement FromIterator +/// impl FromIterator for MyCollection { +/// fn from_iter>(iterator: I) -> Self { +/// let mut c = MyCollection::new(); +/// +/// for i in iterator { +/// c.add(i); +/// } +/// +/// c +/// } +/// } +/// +/// // Now we can make a new iterator... +/// let iter = (0..5).into_iter(); +/// +/// // ... and make a MyCollection out of it +/// let c = MyCollection::from_iter(iter); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// +/// // collect works too! +/// +/// let iter = (0..5).into_iter(); +/// let c: MyCollection = iter.collect(); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ built from an iterator over elements of type `{A}`"] pub trait FromIterator: Sized { - /// Builds a container with elements from something iterable. + /// Creates a value from an iterator. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.FromIterator.html /// /// # Examples /// - /// ``` - /// use std::collections::HashSet; - /// use std::iter::FromIterator; + /// Basic usage: /// - /// let colors_vec = vec!["red", "red", "yellow", "blue"]; - /// let colors_set = HashSet::<&str>::from_iter(colors_vec); - /// assert_eq!(colors_set.len(), 3); /// ``` + /// use std::iter::FromIterator; /// - /// `FromIterator` is more commonly used implicitly via the - /// `Iterator::collect` method: + /// let five_fives = std::iter::repeat(5).take(5); /// - /// ``` - /// use std::collections::HashSet; + /// let v = Vec::from_iter(five_fives); /// - /// let colors_vec = vec!["red", "red", "yellow", "blue"]; - /// let colors_set = colors_vec.into_iter().collect::>(); - /// assert_eq!(colors_set.len(), 3); + /// assert_eq!(v, vec![5, 5, 5, 5, 5]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn from_iter>(iterator: T) -> Self; @@ -2415,9 +2501,13 @@ pub trait FromIterator: Sized { /// One benefit of implementing `IntoIterator` is that your type will [work /// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). /// +/// See also: [`FromIterator`]. +/// +/// [`FromIterator`]: trait.FromIterator.html +/// /// # Examples /// -/// Vectors implement `IntoIterator`: +/// Basic usage: /// /// ``` /// let v = vec![1, 2, 3]; @@ -2489,7 +2579,33 @@ pub trait IntoIterator { #[stable(feature = "rust1", since = "1.0.0")] type IntoIter: Iterator; - /// Consumes `Self` and returns an iterator over it. + /// Creates an iterator from a value. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.IntoIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let v = vec![1, 2, 3]; + /// + /// let mut iter = v.into_iter(); + /// + /// let n = iter.next(); + /// assert_eq!(Some(1), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(2), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(3), n); + /// + /// let n = iter.next(); + /// assert_eq!(None, n); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn into_iter(self) -> Self::IntoIter; }