Skip to content

std::iter: document iteration over &T and &mut T #79360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 13, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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.

Implementation note: I haven’t linkified the references to `HashSet` and
`HashMap`, since those are in `std` and these docs are in `core`;
linkifying them gave an “unresolved link” rustdoc error.

Test Plan:
Ran `./x.py doc library/core`, and the result looked good. Manually
copy-pasted the two doctests into the playground and ran them.

wchargin-branch: doc-iter-by-reference
wchargin-source: 0f35369a8a735868621166608797744e97536792
  • Loading branch information
wchargin committed Nov 23, 2020
commit ce3d60476a9f307e71c2928ab575cfced6831187
43 changes: 43 additions & 0 deletions library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,49 @@
//! 2. If you're creating a collection, implementing [`IntoIterator`] for it
//! will allow your collection to be used with the `for` loop.
//!
//! # Iterating by reference
//!
//! Since [`into_iter()`] takes `self` by value, using a `for` loop to iterate
//! over a collection consumes that collection. Often, you may want to iterate
//! over a collection without consuming it. Many collections offer methods that
//! provide iterators over references, conventionally called `iter()` and
//! `iter_mut()` respectively:
//!
//! ```
//! let mut values = vec![41];
//! for x in values.iter_mut() {
//! *x += 1;
//! }
//! for x in values.iter() {
//! assert_eq!(*x, 42);
//! }
//! assert_eq!(values.len(), 1); // `values` is still owned by this function.
//! ```
//!
//! If a collection type `C` provides `iter()`, it usually also implements
//! `IntoIterator` for `&C`, with an implementation that just calls `iter()`.
//! Likewise, a collection `C` that provides `iter_mut()` generally implements
//! `IntoIterator` for `&mut C` by delegating to `iter_mut()`. This enables a
//! convenient shorthand:
//!
//! ```
//! let mut values = vec![41];
//! for x in &mut values { // same as `values.iter_mut()`
//! *x += 1;
//! }
//! for x in &values { // same as `values.iter()`
//! assert_eq!(*x, 42);
//! }
//! assert_eq!(values.len(), 1);
//! ```
//!
//! While many collections offer `iter()`, not all offer `iter_mut()`. For
//! example, mutating the keys of a `HashSet<T>` or `HashMap<K, V>` could put
//! the collection into an inconsistent state if the key hashes change, so these
//! collections only offer `iter()`.
//!
//! [`into_iter()`]: IntoIterator::into_iter
//!
//! # Adapters
//!
//! Functions which take an [`Iterator`] and return another [`Iterator`] are
Expand Down