是否可以使用Vec折叠?

时间:2015-01-03 22:04:37

标签: iterator rust fold

我在考虑如何在Rust中实现Fibonacci,并认为我可以使用fold来实现。

我想出的是以下内容:

range(2, generations).fold(vec![1u, 1], |data: &mut Vec<uint>, value| {
    data.push(data[-2] + data[-1]);

    data
}).last()

然而,这不能编译,因为我无法以借阅检查者喜欢的方式将data Vec放入折叠中。要么它是不可变的,要么是多次借用。或者最后data超出范围,我无法将data返回fold

有没有办法使用Vec折叠?或者我是否必须求助于循环?

1 个答案:

答案 0 :(得分:6)

这是

的工作版本

Rust 2015

fn main() {
    let z = (2..12).fold(vec![1u64, 1], |mut data, _| {
        let next = data[data.len() - 2] + data[data.len() - 1];
        data.push(next);
        data
    });
    println!("{:?}", z.last())
}

Rust 2018

fn main() {
    let z = (2..12).fold(vec![1u64, 1], |mut data, _| {
        data.push(data[data.len() - 2] + data[data.len() - 1]);
        data
    });
    println!("{:?}", z.last())
}

您的方法存在一些问题:

  1. data: &mut Vec<uint>你的累加器变量不是“对可变向量的引用”,它只是一个“可变向量”。
  2. data[-2] Rust不会从数组的后面隐式索引负值。事实上,该指数甚至不接受负值!它需要一个uint,因此您的-2-1会变得非常大!

  3. data.push(data[-2] + data[-1])这对于早于non-lexical lifetimes的Rust版本来说是一个烦恼。编译器看到你正在借用向量(通过获取值),并且你将改变向量。然而,看到读取部分将在写入部分之前完成并不是很聪明,因此您必须拆分临时变量。