我有一个ASCII字符串切片,当被视为字节时,我需要计算所有字符的总和。
let word = "Hello, World";
let sum = word.as_bytes().iter().sum::<u8>();
我需要指定sum的类型,否则Rust将不会编译。问题是u8
是一个太小的类型,如果总和溢出,程序将死机。
我想避免这种情况,但在使用sum()
时,我找不到指定更大类型(例如u16
或u32
(的方法。
我可能会尝试使用fold()
,但我想知道是否有一种方法可以通过指定另一种类型来使用sum()
。
let sum = word.as_bytes().iter().fold(0u32, |acc, x| acc + *x as u32);
您可以使用map
将每个字节强制转换为更大的类型:
let sum: u32 = word.as_bytes().iter().map(|&b| b as u32).sum();
或
let sum: u32 = word.as_bytes().iter().cloned().map(u32::from).sum();
使用最初的尝试无法求和u32
的原因是提供它的Sum
特性具有以下定义:
pub trait Sum<A = Self> {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = A>;
}
这意味着它的方法sum
在默认情况下返回与它所构建的迭代器的项相同的类型。通过查看Sum
:的实现,您可以看到u8
的情况
fn sum<I>(iter: I) -> u8
where
I: Iterator<Item = u8>,