Skip to content

Commit 1698773

Browse files
authored
Rollup merge of #79360 - wchargin:wchargin-doc-iter-by-reference, r=m-ou-se
std::iter: document iteration over `&T` and `&mut T` A colleague of mine is new to Rust, and mentioned that it was “slightly confusing” to figure out what `&mut` does in iterating over `&mut foo`: ```rust for value in &mut self.my_vec { // ... } ``` My colleague had read the `std::iter` docs and not found the answer there. There is a brief section at the top about “the three forms of iteration”, which mentions `iter_mut`, but it doesn’t cover the purpose of `&mut coll` for a collection `coll`. This patch adds an explanatory section to the docs. I opted to create a new section so that it can appear after the note that `impl<I: Iterator> IntoIterator for I`, and it’s nice for the existing “three forms of iteration” to appear near the top. Test Plan: Ran `./x.py doc library/core`, and the result looked good, including links. Manually copy-pasted the two doctests into the playground and ran them. wchargin-branch: doc-iter-by-reference
2 parents f61e5ca + 6edc90a commit 1698773

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

library/core/src/iter/mod.rs

+45
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,51 @@
206206
//! 2. If you're creating a collection, implementing [`IntoIterator`] for it
207207
//! will allow your collection to be used with the `for` loop.
208208
//!
209+
//! # Iterating by reference
210+
//!
211+
//! Since [`into_iter()`] takes `self` by value, using a `for` loop to iterate
212+
//! over a collection consumes that collection. Often, you may want to iterate
213+
//! over a collection without consuming it. Many collections offer methods that
214+
//! provide iterators over references, conventionally called `iter()` and
215+
//! `iter_mut()` respectively:
216+
//!
217+
//! ```
218+
//! let mut values = vec![41];
219+
//! for x in values.iter_mut() {
220+
//! *x += 1;
221+
//! }
222+
//! for x in values.iter() {
223+
//! assert_eq!(*x, 42);
224+
//! }
225+
//! assert_eq!(values.len(), 1); // `values` is still owned by this function.
226+
//! ```
227+
//!
228+
//! If a collection type `C` provides `iter()`, it usually also implements
229+
//! `IntoIterator` for `&C`, with an implementation that just calls `iter()`.
230+
//! Likewise, a collection `C` that provides `iter_mut()` generally implements
231+
//! `IntoIterator` for `&mut C` by delegating to `iter_mut()`. This enables a
232+
//! convenient shorthand:
233+
//!
234+
//! ```
235+
//! let mut values = vec![41];
236+
//! for x in &mut values { // same as `values.iter_mut()`
237+
//! *x += 1;
238+
//! }
239+
//! for x in &values { // same as `values.iter()`
240+
//! assert_eq!(*x, 42);
241+
//! }
242+
//! assert_eq!(values.len(), 1);
243+
//! ```
244+
//!
245+
//! While many collections offer `iter()`, not all offer `iter_mut()`. For
246+
//! example, mutating the keys of a [`HashSet<T>`] or [`HashMap<K, V>`] could
247+
//! put the collection into an inconsistent state if the key hashes change, so
248+
//! these collections only offer `iter()`.
249+
//!
250+
//! [`into_iter()`]: IntoIterator::into_iter
251+
//! [`HashSet<T>`]: ../../std/collections/struct.HashSet.html
252+
//! [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
253+
//!
209254
//! # Adapters
210255
//!
211256
//! Functions which take an [`Iterator`] and return another [`Iterator`] are

0 commit comments

Comments
 (0)