How to sum a slice of bytes reducing the possibility of overflow

Viewed 769

I have an ASCII string slice and I need to compute the sum of all characters when seen as bytes.

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

I need to specify the type for sum, otherwise Rust will not compile. The problem is that u8 is a too small type, and if the sum overflows the program will panic.

I'd like to avoid that, but I cannot find a way to specify a bigger type such as u16 or u32 for example, when using sum().

I may try to use fold(), but I was wondering if there is a way to use sum() by specifying another type.

let sum = word.as_bytes().iter().fold(0u32, |acc, x| acc + *x as u32);
1 Answers

You can use map to cast each byte to a bigger type:

let sum: u32 = word.as_bytes().iter().map(|&b| b as u32).sum();

or

let sum: u32 = word.as_bytes().iter().cloned().map(u32::from).sum();

The reason why you can't sum to u32 using your original attempt is that the Sum trait which provides it has the following definition:

pub trait Sum<A = Self> {
    fn sum<I>(iter: I) -> Self
    where
        I: Iterator<Item = A>;
}

Which means that its method sum returns by default the same type as the items of the iterator it is built from. You can see it's the case with u8 by looking at its implementation of Sum:

fn sum<I>(iter: I) -> u8
where
    I: Iterator<Item = u8>,
Related