Iterators
sum() and product()
The .sum() and .product() consumer methods compute the arithmetic sum or product of all elements in an iterator by delegating to the std::iter::Sum and std::iter::Product traits.
Signatures and Trait Definitions
fn sum<S>(self) -> S
where
Self: Sized,
S: Sum<Self::Item>;
fn product<P>(self) -> P
where
Self: Sized,
P: Product<Self::Item>;
Standard integer and floating-point types (i8..i128, isize, u8..u128, usize, f32, f64, and Wrapping<T>) implement Sum<T>, Sum<&T>, Product<T>, and Product<&T>, meaning both owned iterators (.into_iter()) and borrowed iterators (.iter()) can be summed or multiplied directly:
| Method | Empty Iterator Return Value | Works on Item = T and Item = &T? |
|---|---|---|
.sum::<T>() |
0 (or 0.0 for floats) |
Yes |
.product::<T>() |
1 (or 1.0 for floats) |
Yes |
fn main() {
let values = [2_i32, 3, 4, 5];
let empty: [i32; 0] = [];
let total: i32 = values.iter().sum();
let factorial: i32 = values.iter().product();
println!("Sum: {total}");
println!("Product: {factorial}");
println!("Empty sum: {}", empty.iter().sum::<i32>());
println!("Empty product: {}", empty.iter().product::<i32>());
}
Sum: 14
Product: 120
Empty sum: 0
Empty product: 1
Summing Fallible Iterators (Result<T, E> and Option<T>)
Just like FromIterator, both Result<T, E> (where T: Sum) and Option<T> (where T: Sum) implement Sum. This allows you to sum an iterator yielding Result<i32, E> directly into a Result<i32, E> without allocating an intermediate Vec<i32>, short-circuiting on the first Err:
use std::num::ParseIntError;
fn sum_csv_numbers(cells: &[&str]) -> Result<i64, ParseIntError> {
cells.iter().map(|s| s.parse::<i64>()).sum()
}
fn main() {
println!("Valid CSV: {:?}", sum_csv_numbers(&["10", "25", "65"]));
println!("Invalid CSV: {:?}", sum_csv_numbers(&["10", "bad", "65"]));
}
Valid CSV: Ok(100)
Invalid CSV: Err(ParseIntError { kind: InvalidDigit })
Implementing Sum for a Custom Domain Type
use std::iter::Sum;
#[derive(Debug, Clone, Copy)]
struct DurationMs(u64);
impl Sum for DurationMs {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
DurationMs(iter.map(|d| d.0).sum())
}
}
fn main() {
let intervals = [DurationMs(120), DurationMs(80), DurationMs(300)];
let total: DurationMs = intervals.into_iter().sum();
println!("Total duration: {total:?}");
}
Total duration: DurationMs(500)