The way sum
is defined, the return value is open-ended; more than one type can implement the trait Sum<i32>
. Here’s an example where different types for a
are used, both of which compile:
#[derive(Clone, Copy)]
struct Summer {
s: isize,
}
impl Summer {
fn pow(&self, p: isize) {
println!("pow({})", p);
}
}
impl std::iter::Sum<i32> for Summer {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = i32>,
{
let mut result = 0isize;
for v in iter {
result += v as isize;
}
Summer { s: result }
}
}
fn main() {
let a1: i32 = (1i32..10).sum();
let a2: Summer = (1i32..10).sum();
let b1 = a1.pow(2);
let b2 = a2.pow(2);
}
Playground
Since both result types are possible, the type cannot be inferred and must be explicitly specified, either by a turbofish (sum::<X>()
) or as the result of the expression (let x: X = ...sum();
).