and then sum()
knows to return an i32
这是你出错的地方。退房Iterator::sum
:
fn sum<S>(self) -> S
where S: Sum<Self::Item>
它返回一个泛型类型S
它必须实现Sum
。 S
不是必须匹配Self::Item
。因此,编译器要求您指定将哪些类型归入。
为什么这很有用?从标准库看看这两个样本实现:
impl Sum<i8> for i8
impl<'a> Sum<&'a i8> for i8
这是正确的!你可以总结一个迭代器u8
或迭代器&u8
!如果我们没有这个,那么这段代码是行不通的:
fn main() {
let a: i32 = (0..5).sum();
let b: i32 = [0, 1, 2, 3, 4].iter().sum();
assert_eq!(a, b);
}
As bluss points out,我们可以通过具有相关类型这将领带u8 -> u8
和&'a u8 -> u8
做到这一点。
如果我们只有一个关联类型,那么目标总和类型总是固定的,我们会失去灵活性。例如,我们也可以为我们自己的类型实施Sum
。
在这里,我们总结u8
s,但增加我们正在求和的类型的大小,因为它的总和可能会超过u8
。这种实现是除了从标准库中已有的实现:
#[derive(Debug, Copy, Clone)]
struct Points(i32);
impl std::iter::Sum<u8> for Points {
fn sum<I>(iter: I) -> Points
where I: Iterator<Item = u8>
{
let mut pts = Points(0);
for v in iter {
pts.0 += v as i32;
}
pts
}
}
fn main() {
let total: Points = (0u8..42u8).sum();
println!("{:?}", total);
}
相关问题:http:// stackoverflow。com/q/40243061/1233251 –