Search code examples
for-looprustcontrol-flow

Is there a way to distinguish normal loop termination from break termination in Rust?


Idiomatic for/else in rust:

In Python, I can use for/else to check whether or not a for loop terminated at a break statement or finished 'normally':

prod = 1
for i in range(1, 10):
    prod *= i
    if prod > 123:
        break
else:
    print("oops! loop terminated without break.")

Is there a similar way to do that in Rust? This is the closest I have come, but it is not particularly similar.

let mut prod = 1u64;
let mut found = false;
for i in 1..10 {
    prod *= i;
    if prod > 123 {
        found = true;
        break;
    }
}
if !found {
    println!("oops! loop terminated without break.");
}

There seems to be a discussion about this on rust internals; however, that is more about future possibilities than what is idiomatic.

In Python, idiomatic code is called pythonic - is there a similar word for idiomatic Rust code?


Solution

  • Since Rust 1.65, you can break out of blocks, optionally with a value. Cases like that were even mentioned in the RFC as a motivation:

    let value = 'found: {
        for i in 1..2 {
            prod *= i;
            if prod > 123 {
                break 'found Some(prod);
            }
        }
        println!("oops! loop terminated without break.");
        None
    };
    

    Playground.