13

编者注:这个问题中的代码早于 Rust 1.0。此代码的等效现代版本按原样编译。

我仍然在学习 Rust 的小步骤,并对以下内容感到惊讶。

我不明白为什么这段代码会编译:

use std::iter::AdditiveIterator;

fn main() {

    let range = [1,2,3,4,5,6,7,8,9];
    let sum = range.iter().map(|&x| x * x).filter(|&x| x % 2 == 0).sum();

    println!("{}", sum);
}

虽然这不是:(只是向上移动.iter()

use std::iter::AdditiveIterator;

fn main() {

    let range = [1,2,3,4,5,6,7,8,9].iter();
    let sum = range.map(|&x| x * x).filter(|&x| x % 2 == 0).sum();

    println!("{}", sum);
}

导致此错误:

test.rs:5:17: 5:36 error: borrowed value does not live long enough
test.rs:5     let range = [1,2,3,4,5,6,7,8,9].iter();
                          ^~~~~~~~~~~~~~~~~~~

我确定它与 Rust 作用域等有关,但我不确定我是否理解将方法调用移动到不同的行会产生什么影响。

4

2 回答 2

10

该数组在语句结束时被销毁,let range = [1,2,3,4,5,6,7,8,9].iter();因为没有保存该向量的变量。这将导致悬空迭代器无处指向。

在 C++ 中也是如此,可以在对象上创建迭代器,然后将其删除。

于 2014-05-03T06:03:56.457 回答
1

在现代 Rust 中,等效代码编译为:

fn main() {
    let range = [1, 2, 3, 4, 5, 6, 7, 8, 9].iter();
    let sum: i32 = range.map(|&x| x * x).filter(|&x| x % 2 == 0).sum();
    println!("{}", sum);
}

这是因为像数组字面量一样,字面量现在会在需要时自动提升为静态变量。这里的结果iter现在是一个std::slice::Iter<'static, i32>.

也可以看看:

于 2019-01-07T00:11:09.447 回答