Why is the let keyword in if-let?

Viewed 254

I am learning Rust by the rustbook at the moment and so far i had no problems but if-let makes no sense to me. I think i kinda get what it does but the syntax seems not logical for me and this hinders me to use it.

This Question explains the differences betwenn if an if-let but i read the answers and i still cant grasp it. I dont understand why this syntax was chosen.

The accepted answer from the question i linked has some examples:

if let Foo::Bar = a {
    println!("a is foobar");
}

My first thought was that let is used because we kinda declare a temporary variable and assign a to it and if thats possible the if-block is executed. That would make sense to me. But then i read the next two examples:

if let Foo::Qux(value) = c {
    println!("c is {}", value);
} 
if let Foo::Qux(value @ 100) = c {
    println!("c is one hundred");
}

The terms let Foo::Qux(value) and let Foo::Qux(value @ 100) seem wrong to me. to my understanding i cant declare a variable like this.

What is happening here?

I know about pattern matching but the let keyword makes me feel that there is something i dont get.

Am i right that let mypattern = myvariable is basicaly fn rusts_patternmatching(mypattern, myvariable) ->bool and the syntax is just confusing for me? Why was the let keyword chosen then?


To the comments: To my understanding it is basicaly the same as pattern matching against one arm. But the let keyword seems so wrong for me to express that, that i feel that i am fundamently wrong about the concept in my head. To me "let" is used to declare a variable in rust. Why was it chosen here for something completly different?

1 Answers

Both let and if let work on a single Pattern; name assignment is a side-effect of matching the pattern. For example, let (a, b) = (1, 2) matches (1, 2) to the pattern (a, b).

The difference is that let is a required ("irrefutable") match, whereas if let is a possible ("refutable") match. The possibility of not matching the pattern is expressed by if.

fn main() {
    // don't do this at home
    if let (a, b) = (1, 2) {
        println!("{} {}", a, b);
    };
}

See also RFC 160: if let for the rationale of creating if let as a conditional (if) pattern match (let) and background.

Related