【问题标题】:Is it possible to use a fold with a Vec?是否可以使用带有 Vec 的折叠?
【发布时间】:2015-01-03 22:04:36
【问题描述】:

我正在考虑如何在 Rust 中实现斐波那契,并认为我可以使用 fold 来实现。

我想出的是以下内容:

// Editor's note: this code sample predates Rust 1.0 and 
// is not valid syntax. The concepts remain valid.

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

    data
}).last()

但是,这不会编译,因为我无法以借用检查器喜欢的方式将data 放入fold。它要么是不可变的,要么被多次借用,或者最后一个 data 超出范围,我无法将 data 返回到 fold

有没有办法将折叠与Vec 一起使用?还是我必须求助于循环?

【问题讨论】:

    标签: iterator rust fold


    【解决方案1】:

    这里是a working version

    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: &amp;mut Vec&lt;uint&gt;(或现代 Rust 中的 usize)— 您的累加器变量不是“对可变向量的引用”,它只是一个“可变向量”。
    2. data[-2] — Rust 不会从数组的后面隐式索引负值。事实上,索引甚至不接受负值!它需要一个usize,所以你的-2-1 会变成非常大的数字!

    【讨论】:

    • 太完美了,谢谢!虽然我有一个问题(关于你的第 1 点):我添加了 ref 是因为我认为闭包内的数据将是数据向量的副本,而不是指向同一个数据向量。 Rust 如何决定何时通过引用传递值以及何时通过值传递?
    • Rust 不会为你“决定”任何事情;这完全取决于程序员。 fold 接受 B 类型的初始值和接受 B 和单个迭代器值并返回 B 的函数。在这种情况下,您的 BVec&lt;u64&gt;
    • 另请注意,您的闭包不会从其上下文中捕获任何变量,它只是处理提供给闭包的参数。闭包可以是 Fn、FnOnce 或 FnMut,所有这些都是闭包如何捕获其环境的变体。
    • 我知道我现在的想法哪里出了问题。感谢日志!我认为不使用 ref 会将向量移出fold。但我想它会在关闭结束时被移回,这就是它起作用的原因。
    猜你喜欢
    • 2015-02-08
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 2016-12-25
    相关资源
    最近更新 更多