Comprehensive Rust Ch.16.2 – pattern matching for structs using capture and const expressions

Advertisements

Having trouble understanding the second speaker note point in the Pattern Matching – Destructuring structs of the Comprehensive Rust by Google.

Here is the sample code.

struct Foo {
    x: (u32, u32),
    y: u32,
}

#[rustfmt::skip]
fn main() {
    let foo = Foo { x: (1, 2), y: 3 };
    match foo {
        Foo { x: (1, b), y } => println!("x.0 = 1, b = {b}, y = {y}"),
        Foo { y: 2, x: i }   => println!("y = 2, x = {i:?}"),
        Foo { y, .. }        => println!("y = {y}, other fields were ignored"),
    }
}

And the note in question.

The distinction between a capture and a constant expression can be hard to spot. Try changing the 2 in the second arm to a variable, and see that it subtly doesn’t work. Change it to a const and see it working again.

Thinking my English is bad, but what is it trying to say when it says to observe that it "subtly doesn’t work" when the change is made? Substituting the 2 in y: 2 with something like y: a should still compile?

>Solution :

It means doing:

fn main() {
    let foo = Foo { x: (1, 2), y: 3 };
    let a = 2;
    match foo {
        Foo { x: (1, b), y } => println!("x.0 = 1, b = {b}, y = {y}"),
        Foo { y: a, x: i }   => println!("y = 2, x = {i:?}"),
        Foo { y, .. }        => println!("y = {y}, other fields were ignored"),
    }
}

And expecting it to have the same effect of matching if y is 2, but actually it will match for any y and capture the y in a (shadowing a = 2).

Leave a ReplyCancel reply