This Rust tutorial explains the fold()
mechanism well, and this example code:
let sum = (1..4).fold(0, |sum, x| sum + x);
works as expected.
I'd like to run it on a vector, so based on that example, first I wrote this:
let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, val| sum += val);
which threw an error:
error: binary assignment operation `+=` cannot be applied to types `_` and `&u32` [E0368]
let sum = ratings.values().fold(0, |sum, val| sum += val);
^~~~~~~~~~
I guessed this might be a reference-related error for some reason, so I changed that to fold(0, |sum, &val| sum += val)
, which resulted in
error: mismatched types:
expected `u32`,
found `()`
Hm, maybe something's wrong with the closure? Using {sum += x; sum }
, I got
binary assignment operation `+=` cannot be applied to types `_` and `&u32`
again.
After further trial and error, adding mut
to sum
worked:
let sum = vec![1,2,3,4,5,6].iter().fold(0, |mut sum, &x| {sum += x; sum});
Could someone explain the reason why fold()
for vectors differs so much from the tutorial? Or is there a better way to handle this?
For reference, I'm using Rust beta, 2015-04-02.
Since Rust 1.11, you can
sum
the iterator directly, skippingfold
:You've already figured out that
+=
is the problem, but I'd like to provide some more exposition.In your case, the arguments provided to the
fold
closure are_
and&u32
. The first type is an not-yet-specified integer. If you change your fold call tofold(0u32, |sum, val| sum += val)
, you'll get a slightly different message:The result value of the binary assignment operation
+=
is()
, the unit type. This explains the error message when you changed tofold(0, |sum, &val| sum += val)
:If you change to
fold(0, |sum, &val| {sum += val ; sum})
, you then get an understandable error about immutable variables:From here, you could mark
sum
as mutable, but the correct solution is to simply fold withsum + val
, as you discovered.So it turned out there was a huge difference in my code, as I wrote
sum += x
instead of
sum + x
.Well, at least I hope this question helps, in case someone gets into similar situation.