Early-breaking from Rust's match

后端 未结 3 1552
死守一世寂寞
死守一世寂寞 2021-01-05 05:01

I want to switch through many possible cases for x and there\'s one case (here x == 0) where I want to check the result of some additional code to

相关标签:
3条回答
  • 2021-01-05 05:42

    You can wrap the match into a loop that only runs once and break out of the loop

    fn main() {
        let x = 1;
    
        loop { match x {
            1 => {
                let y = 0;
                /*
                 * do ev1l stuff to y that I don't want to put into the match-guard
                 * as it's simply too much.
                 */
    
                /* break early ... */
                if y == 0 { break; }
    
                assert!(y != 0, "y was 0!");
                /* do other stuff in here. */
            }
            _ => {}
        } break; }
    
        println!("done matching");
    }
    
    0 讨论(0)
  • 2021-01-05 05:46

    Something else you could do is make a "self-executing" closure and use a return statement inside. I don't know whether there are any weird performance characteristics of this but syntactically it's pretty clean.

    fn main() {
        let x = 1;
    
        // This closure is just used to catch the "return" statement.
        (|| {
            match x {
                1 => {
                    let y = 0;
                    /*
                     * do ev1l stuff to y that I don't want to put into the match-guard
                     * as it's simply too much.
                     */
    
                    /* break early ... */
                    if y == 0 { return; } // Ok!
    
                    assert!(y != 0, "y was 0!");
                    /* do other stuff in here. */
                }
                _ => {}
            }
        })();
    
        println!("done matching");
    }
    

    Here's a playground link showing it working.

    0 讨论(0)
  • 2021-01-05 05:53

    You could create a macro like

    macro_rules! block {
        ($xs:block) => {
            loop { let _ = $xs; break; }
        };
    }
    

    and do

    match x {
        1 => block!({
            ...
            if y == 0 { break; }
            ...
        })
        _ => {}
    }
    

    It's not an amazing solution, but it is semantically meaningful.

    0 讨论(0)
提交回复
热议问题