How to iterate over all byte values (overflowing_l

2020-02-07 02:11发布

I'm trying to iterate over all possible byte (u8) values. Unfortunately my range literals in 0..256 are cast to u8 and 256 overflows:

fn foo(byte: u8) {
    println!("{}", byte);
}

fn main() {
    for byte in 0..256 {
        foo(byte);
        println!("Never executed.");
    }
    for byte in 0..1 {
        foo(byte);
        println!("Executed once.");
    }
}

The above compiles with:

warning: literal out of range for u8
 --> src/main.rs:6:20
  |
6 |     for byte in 0..256 {
  |                    ^^^
  |
  = note: #[warn(overflowing_literals)] on by default

The first loop body is never executed at all.

My workaround is very ugly and feels brittle because of the cast:

for short in 0..256 {
    let _explicit_type: u16 = short;
    foo(short as u8);
}

Is there a better way?

标签: rust
2条回答
做个烂人
2楼-- · 2020-02-07 02:42

This is issue Unable to create a range with max value.

The gist of it is that byte is inferred to be u8, and therefore 0..256 is represented as a Range<u8> but unfortunately 256 overflows as an u8.

The current work-around is to use a larger integral type and cast to u8 later on since 256 is actually never reached.

There is a RFC for inclusive range with ... which has entered final comment period; maybe in the future it'll be possible to have for byte in 0...255 or its alternative (0..255).inclusive().

查看更多
放荡不羁爱自由
3楼-- · 2020-02-07 02:57

As of Rust 1.26, inclusive ranges are stabilized using the syntax ..=, so you can write this as:

for byte in 0..=255 {
    foo(byte);
}
查看更多
登录 后发表回答