从函数返回的迭代器的生存期要求冲突

Conflicting lifetime requirement for iterator returned from function

这可能是重复的。我不知道。我无法很好地理解其他答案以了解这一点。 :)

Rust 版本:rustc 1.0.0-nightly (b47aebe3f 2015-02-26)(内置于 2015-02-27)

基本上,我向这个函数传递了一个布尔值,它应该构建一个迭代器,以一种方式过滤为真,另一种方式为假。然后它自己有点胡扯,因为它不知道如何方便地保存该布尔值,我猜。我不知道。这里实际上存在多个生命周期问题,这令人沮丧,因为这对我来说真的常见模式,因为我来自 .NET 背景。

fn main() {
    for n in values(true) {
        println!("{}", n);
    }
}

fn values(even: bool) -> Box<Iterator<Item=usize>> {
    Box::new([3usize, 4, 2, 1].iter()
        .map(|n| n * 2)
        .filter(|n| if even {
            n % 2 == 0
        } else {
            true
        }))
}

有没有办法让它工作?

你有两个相互矛盾的问题,所以让我们分解几个有代表性的部分:

[3usize, 4, 2, 1].iter()
    .map(|n| n * 2)
    .filter(|n| n % 2 == 0))

在这里,我们在方法的堆栈帧中创建一个数组,然后获取指向它的迭代器。由于我们不允许使用数组,因此迭代器项是 &usize。然后我们从 &usize 映射到 usize。然后我们根据 &usize 进行过滤 - 我们不允许使用过滤后的项目,否则迭代器不会将其设置为 return!

这里的问题是,我们最终是扎根于函数的栈帧。我们不能 return 这个迭代器,因为调用 returns!

之后数组将不存在

为了暂时解决这个问题,让我们将其设为静态。现在我们可以专注于 even 的问题。

filter 关闭。闭包捕获任何未作为参数提供给闭包的变量。默认情况下,这些变量是通过引用捕获的。然而,even 又是一个位于堆栈帧上的变量。然而这一次,我们可以使用 move 关键字将其传递给闭包。这是所有内容:

fn main() {
    for n in values(true) {
        println!("{}", n);
    }
}

static ITEMS: [usize; 4] = [3, 4, 2, 1];

fn values(even: bool) -> Box<Iterator<Item=usize>> {
    Box::new(ITEMS.iter()
        .map(|n| n * 2)
        .filter(move |n| if even {
            n % 2 == 0
        } else {
            true
        }))
}