Search code examples
while-loopreturnrust

Return Option inside Loop


The program aims to use a loop to check if the index of a iterator variable meets certain criteria (i.g., index == 3). If find the desired index, return Some(123), else return None.

fn main() {
    fn foo() -> Option<i32> {
        let mut x = 5;
        let mut done = false;

        while !done {
            x += x - 3;

            if x % 5 == 0 {
                done = true;
            }

            for (index, value) in (5..10).enumerate() {
                println!("index = {} and value = {}", index, value);

                if index == 3 {
                    return Some(123);
                }
            }
            return None; //capture all other other possibility. So the while loop would surely return either a Some or a None
        }
    }
}

The compiler gives this error:

error[E0308]: mismatched types
  --> <anon>:7:9
   |
7  |         while !done {
   |         ^ expected enum `std::option::Option`, found ()
   |
   = note: expected type `std::option::Option<i32>`
   = note:    found type `()`

I think the error source might be that a while loop evaluates to a (), thus it would return a () instead of Some(123). I don't know how to return a valid Some type inside a loop.


Solution

  • The value of any while true { ... } expression is always (). So the compiler expects your foo to return an Option<i32> but finds the last value in your foo body is ().

    To fix this, you can add a return None outside the original while loop. You can also use the loop construct like this:

    fn main() {
    
        // run the code
        foo();
    
        fn foo() -> Option<i32> {
            let mut x = 5;
    
            loop {
                x += x - 3;
    
                for (index, value) in (5..10).enumerate() {
                    println!("index = {} and value = {}", index, value);
    
                    if index == 3 {
                        return Some(123);
                    }
                }
                if x % 5 == 0 {
                    return None;
                }
            }
        }
    }
    

    The behaviour of while true { ... } statements is maybe a bit quirky and there have been a few requests to change it.