在递归函数中链接本地迭代器时的生存期问题

问题描述 投票:3回答:1

我有一个通用函数,该函数被递归调用,并且可以接受可以转换为迭代器的参数。

我想将作为参数传递的迭代器与从函数本地集合创建的迭代器进行链接。这个想法是,在多次调用递归函数后,将创建一个单一的迭代器,该迭代器可以迭代位于其各自堆栈框架中的所有集合。

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());
}

不幸的是,当我尝试编译代码时,出现以下错误。

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

我在Rust方面没有太多的经验,我被困在这里,但我认为这似乎不是一件不可能的事情...


编辑:改进的示例代码,由于Stargateur的answer中的提示,因此仅克隆了迭代器,而不克隆整个集合”>

我有一个通用函数,该函数被递归调用,并且可以采用可以转换为迭代器的参数。我想将作为参数传递的迭代器与...

recursion rust iterator lifetime chain
1个回答
2
投票

您将新数组的寿命与函数以外的寿命'a绑定在一起,这是生命周期系统的限制,我认为您无法在今天修复它,也许将来它会编译。但是,即使您可以解决生命周期问题,您也将最终遭受“评估需求的溢流”(E0275)。编译器需要推断无限数量的函数,因为此函数具有无限链结构的无限调用。

© www.soinside.com 2019 - 2024. All rights reserved.