如何使用折叠对矢量求和?

时间:2015-04-09 20:55:46

标签: vector rust

This Rust教程很好地解释了fold()机制,以及此示例代码:

let sum = (1..4).fold(0, |sum, x| sum + x);

按预期工作。

我想在矢量上运行它,所以基于这个例子,首先我写了这个:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, val| sum += val);

引发了错误:

error: binary assignment operation `+=` cannot be applied to types `_` and `&u32` [E0368]
let sum = ratings.values().fold(0, |sum, val| sum += val);
                                              ^~~~~~~~~~

由于某种原因,我猜这可能是与参考相关的错误,因此我将其更改为fold(0, |sum, &val| sum += val),这导致了

error: mismatched types:
expected `u32`,
   found `()`
嗯,关闭可能有些问题?使用{sum += x; sum },我得到了

binary assignment operation `+=` cannot be applied to types `_` and `&u32`

试。

经过进一步的反复试验,将mut添加到sum工作:

let sum = vec![1,2,3,4,5,6].iter().fold(0, |mut sum, &x| {sum += x; sum});

有人可以解释为什么fold()向量与教程有很大差异的原因吗?或者有更好的方法来解决这个问题吗?

作为参考,我正在使用Rust beta,2015-04-02。

2 个答案:

答案 0 :(得分:31)

你已经发现+=是问题,但我想提供一些更多的说明。

在您的情况下,提供给fold闭包的参数是_&u32。第一种类型是尚未指定的整数。如果您将弃牌率更改为fold(0u32, |sum, val| sum += val),则会收到略有不同的消息:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0u32, |sum, val| sum += val);
error[E0308]: mismatched types
  |
2 |     let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0u32, |sum, val| sum += val);
  |                                                                          ^^^ expected u32, found &{integer}
  |
  = note: expected type `u32`
  = note:    found type `&{integer}`

二进制赋值操作+=的结果值是(),单位类型。这解释了更改为fold(0, |sum, &val| sum += val)时的错误消息:

let mut a = 1;
let what_am_i = a += 1;
println!("{:?}", what_am_i); // => ()

如果更改为fold(0, |sum, &val| {sum += val ; sum}),则可以获得有关不可变变量的可理解错误:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, &val| {sum += val; sum});
error[E0384]: re-assignment of immutable variable `sum`
 --> src/main.rs:2:66
  |
2 |     let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, &val| {sum += val; sum});
  |                                                      ---         ^^^^^^^^^^ re-assignment of immutable variable
  |                                                      |
  |                                                      first assignment to `sum`

从这里开始,您可以sum标记为可变,但正确的解决方案是简单地使用sum + val进行折叠,如您所发现的那样。


在较新版本的Rust中,您也可以直接sum迭代器,跳过fold

let sum: u32 = vec![1,2,3,4,5,6].iter().sum();

答案 1 :(得分:8)

所以事实证明我的代码存在巨大差异,正如我写的那样

sum += x

而不是

sum + x

好吧,至少我希望这个问题有所帮助,万一有人遇到类似的情况。