Recursion 递归函数中链接局部迭代器时的锈蚀生存期问题
我有一个递归调用的泛型函数,它可以接受可以转换为迭代器的参数 我想将作为参数传递的迭代器与从函数本地集合创建的迭代器链接起来。其思想是,在多次调用递归函数之后,将创建一个迭代器,该迭代器能够迭代位于其各自堆栈框架中的所有集合Recursion 递归函数中链接局部迭代器时的锈蚀生存期问题,recursion,rust,iterator,lifetime,chain,Recursion,Rust,Iterator,Lifetime,Chain,我有一个递归调用的泛型函数,它可以接受可以转换为迭代器的参数 我想将作为参数传递的迭代器与从函数本地集合创建的迭代器链接起来。其思想是,在多次调用递归函数之后,将创建一个迭代器,该迭代器能够迭代位于其各自堆栈框架中的所有集合 fn func_taking_iter<'a, I>(vals: I) -> () where I: IntoIterator<Item = &'a u32>, I::IntoIter: Clone, { let
fn func_taking_iter<'a, I>(vals: I) -> ()
where
I: IntoIterator<Item = &'a u32>,
I::IntoIter: Clone,
{
let vals = vals.into_iter();
let mut new_val: [u32; 1] = [0u32; 1];
for x in vals.clone() {
new_val[0] = *x;
}
new_val[0] += 1u32;
if new_val[0] == 10u32 {
for x in vals {
println!("Value {}", *x);
}
return;
}
let res = vals.into_iter().chain(new_val.into_iter());
func_taking_iter(res);
}
fn main() {
let first_val = [0u32; 1];
func_taking_iter(first_val.iter());
}
fn func\u iter,
I::IntoIter:Clone,
{
设vals=vals.into_iter();
让mut new_val:[u32;1]=[0u32;1];
对于vals.clone()中的x{
新值[0]=*x;
}
新值[0]+=1u32;
如果新值[0]==10u32{
以VAL表示的x{
println!(“值{},*x);
}
返回;
}
设res=vals.into_iter().chain(new_val.into_iter());
功能测试(res);
}
fn main(){
让first_val=[0u32;1];
func_taking_iter(first_val.iter());
}
不幸的是,当我试图编译代码时,出现了以下错误
error[E0597]: `new_val` does not live long enough
--> src\main.rs:20:38
|
1 | fn func_taking_iter<'a, I>(vals: I) -> ()
| -- lifetime `'a` defined here
...
20 | let res = vals.into_iter().chain(new_val.into_iter());
| -----------------------^^^^^^^-------------
| | |
| | borrowed value does not live long enough
| argument requires that `new_val` is borrowed for `'a`
...
23 | }
| - `new_val` dropped here while still borrowed
错误[E0597]:`new_val`寿命不够长
-->src\main.rs:20:38
|
1 | fn func_take_iter您将新数组的生存期绑定到生存期'a
即函数之外的生存期,这是生存期系统的一个限制,我认为您今天无法修复它,也许将来它会编译。但是,即使您可以解决生命周期问题,您最终也会遇到“评估需求的溢出”(E0275)。编译器需要推断无限多个函数,因为有一个无限链结构的无限函数调用
我不建议在rust中编写这种代码,链接这么多迭代器是没有效率的。我认为你应该改变你的代码,使用向量。这将为您节省堆栈空间,因为无论如何,您的函数不是尾部递归的,因此您可以以堆栈溢出问题结束
fn func\u take\u iter\u aux(vals:Vec)->Vec{
让new_val=vals.last().copied().unwrap_或(0)+1;
如果新值=10u32{
瓦尔斯
}否则{
设mut-vals=vals;
推送阀(新阀);
辅助功能(VAL)
}
}
fn func___iter,
{
函数(VAL.into.COPYED().COLLET())
}
fn main(){
设vals=func_iter(Some(&0));
以VAL表示的x{
println!(“值{}”,x);
}
}
我尽量满足你的要求。这现在是一个尾部递归函数
请注意,vals.clone()
在您的代码中克隆所有数据,而不仅仅是迭代器,您应该让vals=vals.into_iter()
然后您可以克隆迭代器,当然可以删除I:clone,
您能否更详细地解释一下导致“评估需求的溢出”(E0275)的原因在我的具体案例中有错误吗?我在这个场景中理解它,但我在这里看不到相同的方案。@clockworkman您在编译时使用了静态分派,所以泛型I
在第一次调用中(简化)Slice1
然后是Chain
然后是Chain
等等,没有结束,我想用dyn dispatch可以解决这个问题,但这是一个非常糟糕的主意