Recursion 如何在没有运行时多态性的情况下在迭代器上执行N次“平面映射”(或类似操作)?
我希望能够重复一个过程,在这个过程中,我们正在迭代的集合被改变n次。n仅在运行时已知,并且可以由用户指定,因此我们无法将其硬编码到类型中 一种通过在迭代之间收集数据来使用中间数据结构的方法是可行的,如下所示:Recursion 如何在没有运行时多态性的情况下在迭代器上执行N次“平面映射”(或类似操作)?,recursion,rust,iterator,traits,recursive-type,Recursion,Rust,Iterator,Traits,Recursive Type,我希望能够重复一个过程,在这个过程中,我们正在迭代的集合被改变n次。n仅在运行时已知,并且可以由用户指定,因此我们无法将其硬编码到类型中 一种通过在迭代之间收集数据来使用中间数据结构的方法是可行的,如下所示: let n = 10; let mut vec1 = vec![1, 2, 3]; { for _index in 0..n { let temp_vec = vec1.into_iter().flat_map(|x| vec![x, x * 2]).collec
let n = 10;
let mut vec1 = vec![1, 2, 3];
{
for _index in 0..n {
let temp_vec = vec1.into_iter().flat_map(|x| vec![x, x * 2]).collect();
vec1 = temp_vec;
}
}
然而,这似乎是浪费,因为我们正在创建中间数据结构,所以我继续寻找直接链接迭代器的解决方案
起初,我认为人们可以做一些事情,比如:
let mut iter = vec![1, 2, 3].into_iter();
for index in 0..n {
iter = iter.flat_map(|x| vec![x, x * 2].into_iter());
}
但是,这不起作用,因为在Rust中,迭代器上的所有函数都返回自己的“复合迭代器”结构。例如,在Haskell中,迭代器上的函数返回适当类型的结果迭代器,这不会成为“越来越大的复合类型”。
将其重写为递归函数也有类似的问题,因为a I返回“某种类型的迭代器”,其类型接近-由于递归,无法手动写出,而b这种类型在基本情况下与递归情况不同
我发现有条件地返回一个或另一个迭代器类型,以及使用impl iterator指示返回实现迭代器特性的具体类型,但我们不关心它的确切性质。
下面的代码中实现了一个与链接答案中的代码类似的示例,可能是_flatmap。这很有效
但是,我不想在传入的迭代器上运行平面映射零次或一次,而是N次。因此,我对代码进行了调整,使其能够递归地调用自己,深度达到N
尝试执行此操作时,会使Rust编译器发出错误[E0720]:不透明类型扩展为递归类型:
错误[E0720]:不透明类型扩展为递归类型
->src/main.rs:16:65
|
16 | fn rec|u flatmapier:T,深度:usize->impl迭代器{
|^^^^^^^^^^^^^^^^^^^^^^^^^^扩展为递归类型
|
=注意:扩展类型为`other::other`
我被卡住了
因为不管你多久使用一次平面映射,最终的答案是一个整数向量上的迭代器,似乎应该有一种只使用一个具体返回类型来编写这个函数的方法
这是可能的吗?有没有一种不用运行时多态性就可以摆脱这种情况的方法
我相信/希望没有动态多态特性对象或类似对象的解决方案是可能的,因为无论您调用flat_map的频率有多高,最终结果至少在道义上应该具有相同的类型。我希望有一种方法可以将不匹配的嵌套FlatMap结构以某种方式固定在匹配的单个静态类型中
有没有一种方法可以在没有运行时多态性的情况下解决这个问题
没有
要使用特征对象解决此问题,请执行以下操作:
let mut iter: Box<dyn Iterator<Item = i32>> = Box::new(vec![1, 2, 3].into_iter());
for _ in 0..n {
iter = Box::new(iter.flat_map(|x| vec![x, x * 2].into_iter()));
}
不管你称之为平面图的频率有多高,最终结果至少在道德上应该是相同的类型
我不知道哪种道德适用于类型系统,但FlatMap和FlatMap内存中的文字大小很可能不同,它们是不同的类型
另见:
@Shepmaster我已经澄清了这个问题:我相信/希望没有动态多态性特征对象或类似对象的解决方案是可能的,因为无论您调用flat_map的频率有多高,最终结果至少在道义上应该具有相同的类型。因此我希望有一种方法将不匹配的嵌套FlatMap结构固定在匹配的sin中不知何故,gle静态类型。n只能在运行时知道,并且可以由用户指定。那么为什么您认为它可以被编码到类型系统中,而不是动态解析?我不知道Haskell会如何处理它,但我想象类似于Box的东西。如果n在编译时未知,编译器无法生成任何n。@trentcl你可能是正确的,我知道一个标准的Haskell,所有的值都是装箱的,B如@ Shepmaster指出的那样,像递归语言这样的函数可以编译的唯一情况是,不管有多少个内存大小,因此多态的函数变体存储在二进制代码中考虑,WHIC。h对于递归类型,只有通过指针类型等进行间接寻址时,才会出现这种情况。
let mut iter: Box<dyn Iterator<Item = i32>> = Box::new(vec![1, 2, 3].into_iter());
for _ in 0..n {
iter = Box::new(iter.flat_map(|x| vec![x, x * 2].into_iter()));
}