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

时间:2015-02-27 21:21:15

标签: iterator closures rust lifetime

这可能是重复的。我不知道。我不能很好地理解其他答案。 :)

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

基本上,我将bool传递给这个函数,该函数应该构建一个迭代器,它过滤一种方式为true,另一种方式为false。然后它有点像自己,因为它不知道如何保持这个布尔值的方便,我想。我不知道。这里实际上存在多个生命周期问题,这是令人沮丧的,因为这对我来说是一个真正的常见模式,因为我来自.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
        }))
}

有没有办法让这项工作?

1 个答案:

答案 0 :(得分:2)

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

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

这里,我们在方法的堆栈框架中创建一个数组,然后获取它的迭代器。由于我们不允许使用数组,因此迭代器项为&usize。然后,我们会从&usize映射到usize。然后我们过滤&usize - 我们不允许使用过滤的项目,否则迭代器不会让它返回!

这里的问题是我们最终根植于函数的堆栈框架。我们无法返回此迭代器,因为在调用返回后数组将不存在!

现在解决这个问题,让我们把它变成静态的。现在我们可以专注于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
        }))
}