您能否创建一个函数,该函数接受另一个函数和一个参数并返回嵌套函数调用的延迟流?



在Clojure中,我使用一个名为iterate的函数:

返回 x、(f x(、(f (f x(( 等的延迟序列,f 必须没有副作用

Rust 中有类似的东西吗?

例如,我有一个函数,我想传递给一个带有数字的函数,然后迭代流/范围/向量,直到找到Some(1)

fn coltz(n: u64) -> Option<u64> {
match n % 2 {
0 => Some(n / 2), 
_ => Some(3 * n + 1)
}
}

您可以使用std::iter::repeat_with()重复调用闭包:

repeat_with(move || {
let result = x;
x = f(x);
result
})

返回值是对闭包的连续返回值的迭代器。

我们使用movex移动到闭包中,作为迭代的当前状态。 在闭包中,我们使用f(x)更新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);
}
}

操场

从 Rust 1.34 开始,您可以使用iter::successors

fn coltz(n: u64) -> Option<u64> {
match n % 2 {
0 => Some(n / 2),
_ => Some(3 * n + 1),
}
}
use std::iter;
fn main() {
let sequence = iter::successors(Some(10), |&v| coltz(v)).take_while(|&v| v != 1);
for v in sequence {
println!("{}", v);
}
}
12
6
3
10
5
16
8
4
2

最新更新