4

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?

HrkBrkkl
  • 613
  • 5
  • 22
  • 2
    did you read about pattern matching before ? match ? – Stargateur Mar 07 '21 at 11:40
  • yes but i dont get why we have a let in there. Why the syntax was chosen. the let confuses me and i want to understand why it makes for a patternmatching syntax to have it in there. – HrkBrkkl Mar 07 '21 at 11:41
  • Please check the syntax of `if` and `if let` and their possible combination from the [reference](https://doc.rust-lang.org/reference/expressions/if-expr.html). Additional `let` keyword determines that the programmer is trying to destruct the object or just doing a logical check. – Ömer Erden Mar 07 '21 at 11:49
  • @ÖmerErden can you ellaborate on the use of the let keyword? – HrkBrkkl Mar 07 '21 at 12:05
  • 3
    Can you clarify what you are asking with "why"? Are you wondering specifically why the ``let`` keyword is used here and not another *word*? Are you wondering whether the ``let`` in ``if let`` and a bare ``let`` are the same? Are you aware that both ``let`` and ``if let`` fundamentally work on [Patterns](https://doc.rust-lang.org/reference/patterns.html)? – MisterMiyagi Mar 07 '21 at 12:09
  • @MisterMiyagi yes i am asking why let and not another word (but only if this let and the let is use when i declare a variable have different meaning). Yes i am wondering if the let in if let and let are the same. No i am not aware that a bare let has to do with Patterns. – HrkBrkkl Mar 07 '21 at 12:14
  • `if let` means 'if pattern matches, open new scope and bind the matched value in that scope'. – Ivan C Mar 07 '21 at 12:28
  • @goodsnek I am not sure why the `let` keyword has chosen but I doubt it can be considered as wrong. Please check the code(2nd block in Motivation section)from the [RFC](https://github.com/rust-lang/rfcs/blob/master/text/0160-if-let.md). It consists by 2 operation. Checks the pattern then assigns it to a variable. For Rust there is 2 keyword that do this job, first one is `if` and the latter one is `let`. – Ömer Erden Mar 07 '21 at 12:32

1 Answers1

6

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.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • I finally "got" it with the formal specification: `if let PAT = EXPR { BODY }`. Does the EXPR match the PAT? if so then us the bindings in the PAT to do BODY. – pablete May 29 '23 at 23:04