@@ -1,6 +1,6 @@
|
||||
# Iteration
|
||||
|
||||
During the very first exercises, you learned that Rust lets you iterate over collections using `for` loops.
|
||||
During the very first exercises, you learned that Rust lets you iterate over collections using `for` loops.
|
||||
We were looking at ranges at that point (e.g. `0..5`), but the same holds true for collections like arrays and vectors.
|
||||
|
||||
```rust
|
||||
@@ -35,13 +35,13 @@ loop {
|
||||
}
|
||||
```
|
||||
|
||||
`loop` is another looping construct, on top of `for` and `while`.
|
||||
`loop` is another looping construct, on top of `for` and `while`.\
|
||||
A `loop` block will run forever, unless you explicitly `break` out of it.
|
||||
|
||||
## `Iterator` trait
|
||||
|
||||
The `next` method in the previous code snippet comes from the `Iterator` trait.
|
||||
The `Iterator` trait is defined in Rust's standard library and provides a shared interface for
|
||||
The `Iterator` trait is defined in Rust's standard library and provides a shared interface for
|
||||
types that can produce a sequence of values:
|
||||
|
||||
```rust
|
||||
@@ -53,16 +53,16 @@ trait Iterator {
|
||||
|
||||
The `Item` associated type specifies the type of the values produced by the iterator.
|
||||
|
||||
`next` returns the next value in the sequence.
|
||||
It returns `Some(value)` if there's a value to return, and `None` when there isn't.
|
||||
`next` returns the next value in the sequence.\
|
||||
It returns `Some(value)` if there's a value to return, and `None` when there isn't.
|
||||
|
||||
Be careful: there is no guarantee that an iterator is exhausted when it returns `None`. That's only
|
||||
guaranteed if the iterator implements the (more restrictive)
|
||||
guaranteed if the iterator implements the (more restrictive)
|
||||
[`FusedIterator`](https://doc.rust-lang.org/std/iter/trait.FusedIterator.html) trait.
|
||||
|
||||
## `IntoIterator` trait
|
||||
|
||||
Not all types implement `Iterator`, but many can be converted into a type that does.
|
||||
Not all types implement `Iterator`, but many can be converted into a type that does.\
|
||||
That's where the `IntoIterator` trait comes in:
|
||||
|
||||
```rust
|
||||
@@ -73,15 +73,15 @@ trait IntoIterator {
|
||||
}
|
||||
```
|
||||
|
||||
The `into_iter` method consumes the original value and returns an iterator over its elements.
|
||||
The `into_iter` method consumes the original value and returns an iterator over its elements.\
|
||||
A type can only have one implementation of `IntoIterator`: there can be no ambiguity as to what `for` should desugar to.
|
||||
|
||||
One detail: every type that implements `Iterator` automatically implements `IntoIterator` as well.
|
||||
One detail: every type that implements `Iterator` automatically implements `IntoIterator` as well.
|
||||
They just return themselves from `into_iter`!
|
||||
|
||||
## Bounds checks
|
||||
|
||||
Iterating over iterators has a nice side effect: you can't go out of bounds, by design.
|
||||
Iterating over iterators has a nice side effect: you can't go out of bounds, by design.\
|
||||
This allows Rust to remove bounds checks from the generated machine code, making iteration faster.
|
||||
|
||||
In other words,
|
||||
@@ -103,5 +103,5 @@ for i in 0..v.len() {
|
||||
```
|
||||
|
||||
There are exceptions to this rule: the compiler can sometimes prove that you're not going out of bounds even
|
||||
with manual indexing, thus removing the bounds checks anyway. But in general, prefer iteration to indexing
|
||||
with manual indexing, thus removing the bounds checks anyway. But in general, prefer iteration to indexing
|
||||
where possible.
|
||||
|
||||
Reference in New Issue
Block a user