Вы можете повторно вызывать замыкание, используя std::iter::repeat_with()
:
repeat_with(move || {
let result = x;
x = f(x);
result
})
Возвращаемое значение является итератором последовательных возвращаемых значений замыкания.
Мы используем move
для перемещения x
в замыкание, как текущее состояние нашей итерации.Внутри замыкания мы обновляем x
на f(x)
и возвращаем старое значение (поэтому в первой итерации мы возвращаем исходное x
).
Вот полный рабочий пример:
use std::iter::repeat_with;
fn collatz(n: u64) -> u64 {
match n % 2 {
0 => n / 2,
_ => 3 * n + 1,
}
}
fn iterate<F, X>(f: F, mut x: X) -> impl Iterator<Item = X>
where
F: Fn(X) -> X,
X: Copy,
{
repeat_with(move || {
let result = x;
x = f(x);
result
})
}
fn main() {
for i in iterate(collatz, 12).take_while(|&x| x != 1) {
println!("{}", i);
}
}
Детская площадка