如何对字节片求和以减少溢出的可能性



我有一个ASCII字符串切片,当被视为字节时,我需要计算所有字符的总和。

let word = "Hello, World";
let sum = word.as_bytes().iter().sum::<u8>();

我需要指定sum的类型,否则Rust将不会编译。问题是u8是一个太小的类型,如果总和溢出,程序将死机。

我想避免这种情况,但在使用sum()时,我找不到指定更大类型(例如u16u32(的方法。

我可能会尝试使用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>,

最新更新