Трейт Iterator
Трейт Iterator описывает итератор - тип,
который умеет выдавать последовательность значений
по одному элементу за раз. Основным методом трейта
является next, который возвращает
Some(элемент), пока элементы не закончатся,
и None, когда итератор исчерпан. Параметров
метод next не принимает, но получает
изменяемую ссылку на самого себя. Все остальные
методы трейта - такие как map,
filter, collect, fold и многие
другие - являются методами по умолчанию и строятся
поверх next. Итераторы бывают адаптерами
(ленивыми) и потребителями (вызывающими обход).
Синтаксис
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
Пример
Давайте обойдём вектор vec![1, 2, 3, 4, 5]
с помощью метода iter и выведем каждый
элемент в цикле:
fn main()
{
let vec = vec![1, 2, 3, 4, 5];
for item in vec.iter()
{
println!("{}", item);
}
}
Результат выполнения кода:
1
2
3
4
5
Пример
Давайте вручную вызовем метод next
у итератора и получим элементы по одному:
fn main()
{
let vec = vec!["a", "b", "c", "d", "e"];
let mut iter = vec.iter();
println!("{:?}", iter.next());
println!("{:?}", iter.next());
println!("{:?}", iter.next());
println!("{:?}", iter.next());
println!("{:?}", iter.next());
println!("{:?}", iter.next());
}
Результат выполнения кода:
Some("a")
Some("b")
Some("c")
Some("d")
Some("e")
None
Пример
Давайте применим метод map, чтобы
преобразовать каждый элемент, и метод
collect, чтобы собрать результат в вектор:
fn main()
{
let res: Vec<i32> = vec![1, 2, 3, 4, 5]
.iter()
.map(|x| x * 2)
.collect();
println!("{:?}", res);
}
Результат выполнения кода:
[2, 4, 6, 8, 10]
Пример
Давайте используем метод filter, чтобы
оставить только чётные числа, и метод sum,
чтобы просуммировать их:
fn main()
{
let res: i32 = vec![1, 2, 3, 4, 5]
.iter()
.filter(|x| *x % 2 == 0)
.sum();
println!("{}", res);
}
Результат выполнения кода:
6
Пример
Давайте создадим собственный итератор,
реализовав трейт Iterator для структуры,
которая выдаёт числа от 1 до 3:
struct Counter
{
current: u32,
max: u32,
}
impl Iterator for Counter
{
type Item = u32;
fn next(&mut self) -> Option<Self::Item>
{
if self.current < self.max
{
self.current += 1;
Some(self.current)
}
else
{
None
}
}
}
fn main()
{
let counter = Counter { current: 0, max: 3 };
for value in counter
{
println!("{}", value);
}
}
Результат выполнения кода:
1
2
3