snippetrustMajor
How do I sum a vector using fold?
Viewed 0 times
howusingsumvectorfold
Problem
This Rust tutorial explains the
works as expected.
I'd like to run it on a vector, so based on that example, first I wrote this:
which threw an error:
I guessed this might be a reference-related error for some reason, so I changed that to
Hm, maybe something's wrong with the closure? Using
again.
After further trial and error, adding
Could someone explain the reason why
For reference, I'm using Rust beta, 2015-04-02.
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 inerror: mismatched types:
expected `u32`,
found `()`Hm, maybe something's wrong with the closure? Using
{sum += x; sum }, I gotbinary 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.
Solution
Since Rust 1.11, you can
You've already figured out that
In your case, the arguments provided to the
The result value of the binary assignment operation
If you change to
From here, you could mark
sum the iterator directly, skipping fold:let sum: u32 = vec![1, 2, 3, 4, 5, 6].iter().sum();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 to fold(0u32, |sum, val| sum += val), you'll get a slightly different message: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}
The result value of the binary assignment operation
+= is (), the unit type. This explains the error message when you changed to fold(0, |sum, &val| sum += val):let mut a = 1;
let what_am_i = a += 1;
println!("{:?}", what_am_i); // => ()If you change to
fold(0, |sum, &val| {sum += val ; sum}), you then get an understandable error about immutable variables: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
From here, you could mark
sum as mutable, but the correct solution is to simply fold with sum + val, as you discovered.Code Snippets
let sum: u32 = vec![1, 2, 3, 4, 5, 6].iter().sum();let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0u32, |sum, val| sum += val);let mut a = 1;
let what_am_i = a += 1;
println!("{:?}", what_am_i); // => ()let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, &val| {sum += val; sum});Context
Stack Overflow Q#29548819, score: 72
Revisions (0)
No revisions yet.