wiki/content/20200923150006-iterators.md

141 lines
2.2 KiB
Markdown

---
date: 2020-09-23
id: a01bfc26-dece-4741-829b-d164ba9522bb
title: Rust Iterators
---
# Syntax
``` rust
fn main() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
println!("Got: {}", val);
}
}
```
# Iterator Trait
All iterators implement a [trait](20200917163203-traits) named
[Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html)
``` rust
#![allow(unused)]
fn main() {
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
// methods with default implementations elided
}
}
```
# Iterator methods
## next
``` rust
#[cfg(test)]
mod tests {
#[test]
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
}
}
fn main() {}
```
## sum
``` rust
#[cfg(test)]
mod tests {
#[test]
fn iterator_sum() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
}
}
fn main() {}
```
# Methods that produce other Iterators
By their nature iterators are lazy so the following won't work:
``` rust
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
v1.iter().map(|x| x + 1);
}
```
The Iterator must be consumed, using the
[collect](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect)
method:
``` rust
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
}
```
# Creating your own Iterators
``` rust
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 5 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let counter = Counter::new();
for val in counter {
println!("Got: {}", val);
}
}
```