Адаптер над своим обходом в Rust
Адаптер оборачивает чужой обход и меняет элемент перед отдачей. Внутри хранится другой обход как поле, а метод следующего элемента спрашивает у него значение и возвращает уже преобразованный результат.
Сначала снова опишем счетчик, затем обертку, которая удваивает каждое число:
struct Count {
n: i32,
end: i32,
}
impl Iterator for Count {
type Item = i32;
fn next(&mut self) -> Option<i32> {
if self.n >= self.end {
None
} else {
let v = self.n;
self.n += 1;
Some(v)
}
}
}
struct Double<I> {
inner: I,
}
impl<I> Iterator for Double<I>
where
I: Iterator<Item = i32>,
{
type Item = i32;
fn next(&mut self) -> Option<i32> {
match self.inner.next() {
Some(v) => Some(v * 2),
None => None,
}
}
}
fn main() {
let base = Count { n: 0, end: 3 };
let mut doubled = Double { inner: base };
while let Some(x) = doubled.next() {
println!("{}", x);
}
}
На экране 0, 2 и 4:
счетчик по-прежнему выдает 0,
1 и 2, а адаптер умножает
их на два. Пустой ответ с внутреннего
обхода сразу пробрасывается наружу.
Тот же адаптер можно связать с циклом
for, если собрать цепочку в одном
выражении:
struct Count {
n: i32,
end: i32,
}
impl Iterator for Count {
type Item = i32;
fn next(&mut self) -> Option<i32> {
if self.n >= self.end {
None
} else {
let v = self.n;
self.n += 1;
Some(v)
}
}
}
struct Double<I> {
inner: I,
}
impl<I> Iterator for Double<I>
where
I: Iterator<Item = i32>,
{
type Item = i32;
fn next(&mut self) -> Option<i32> {
if let Some(v) = self.inner.next() {
Some(v * 2)
} else {
None
}
}
}
fn main() {
for x in Double {
inner: Count { n: 1, end: 4 },
} {
println!("{}", x);
}
}
Даны структуры:
struct Count {
n: i32,
end: i32,
}
struct AddOne<I> {
inner: I,
}
Выполните трейт обхода для AddOne,
где внутренний обход отдает i32.
К каждому числу прибавьте единицу. Проверьте
на Count { n: 0, end: 2 } и выведите
результат.
Дана структура:
struct Scale<I> {
inner: I,
k: i32,
}
Сделайте адаптер с полем k, который
умножает каждый i32 с внутреннего
обхода на k. Обработайте пустой
ответ через match. Покажите работу
на своем счетчике с k: 3.
Скажите, зачем в описании Double
требовать у поля inner, что это
обход с элементом i32, а не оставлять
поле без такой границы.