Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust match – benefit of @ Operator Bindings over Extra Conditionals with Match Guards

Reading the "The Rust Programming Language"- part "18. Patterns and Matching", chapter "18.3. Pattern Syntax". Towards the end of the chapter, section "@ Bindings" introduces a way to "create a variable that holds a value at the same time we’re testing that value to see whether it matches a pattern". However, I’m struggling to see what value this adds over the approach discussed in section "Extra Conditionals with Match Guards" earlier in the chapter.

For example, taking the "@ Bindings" section’s code example, below I believe I’ve implemented the same logic in both ways, hence I’m not seeing the value of the "@ Bindings" approach.

enum Message {
    Hello { id: i32},
}

fn main() {
    let msg = Message::Hello { id: 5 };

    // @ Binding Operator Example
    match msg {
        Message::Hello { id: idvar @ 3..=7 } => println!("Found an id in range: {}", idvar),
        Message::Hello { id: 10..=12 } => println!("Found an id in another range"),
        Message::Hello { id } => println!("Found some other id: {}", id),
    }            
    // Conditional Match Guard Example
    match msg {
        Message::Hello { id: idvar } if (3..=7).contains(&idvar) => println!("Found an id of range: {}", idvar),
        Message::Hello { id: idvar } if (idvar >= 10 && idvar <=12) => println!("Found an id in another range"),
        Message::Hello { id: idvar } => println!("Found some other id: {}", idvar),
    }                
}

Note: I’m just using two different approaches in the match guard to define q range as an experiment – not directly relevant to the question

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’m sure I’m missing some subtle benefits (maybe not addressed by the simplified example provided in the book). What unique benefits does the @ operator binding approach provide or is it just an alternative approach?

>Solution :

The main difference is exhaustiveness checking. Match guards can’t contribute to exhaustiveness checks in the compiler, so additional cases may be required which could be avoided using bindings. Here’s an example:

let n = 5u8;

// this works: the compiler can tell that together, each arm covers all
// possible cases
match n {
    value @ 0..=127 => println!("low: {}", n),
    value @ 127..=255 => println!("high: {}", n),
}

// this doesn't work: match guards don't contribute to exhaustiveness
// checking, so the compiler isn't sure that all possible cases are covered
// and requires a default case (even though it's unreachable)
match n {
    value if (0..=127).contains(&value) => println!("low: {}", n),
    value if (127..=255).contains(&value) => println!("high: {}", n),
    // uncommenting this line will allow it to compile
    // _ => unreachable!()
}

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading