Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match a struct using reference

Tags:

match

rust

To match a struct while preventing a move, I want to use a reference to do the match. So the following code will do the job:

struct Foo(i32);

fn main() {
    let x = Foo(1);
    match &x {
        ref a => println!("hello"),
    }
    println!("{}", x.0);
}

But I am surprised to find that the following code also works, which actually matched a struct (x) with a reference (ref a). But, shouldn't it be a type mismatch here?

struct Foo(i32);

fn main() {
    let x = Foo(1);
    match x {
        ref a => println!("hello")
    }
    println!("{}", x.0);
}
like image 290
enaJ Avatar asked Jan 18 '26 15:01

enaJ


1 Answers

ref is not a normal part of the pattern that "strips away" something from the value, but is a modifier of the name binding, like mut. It instructs the name to bind to a reference to the value instead of the value directly.

Let's see what type a has in each case:

match &x {
    ref a => {
        let () = a;
    }
}
match x {
    ref b => {
        let () = b;
    }
}

The let () = a; is a trick to find out the type of a. And indeed the compiler tells us:

   |
7  |             let () = a;
   |                 ^^ expected &&Foo, found ()

[...]
   |
12 |             let () = b;
   |                 ^^ expected &Foo, found ()

So in the first case, we have reference to a reference, namely &&Foo. This is because we're matching on the expression &x (type: &Foo) and then tell the compiler to bind the name "by reference".

like image 63
Lukas Kalbertodt Avatar answered Jan 20 '26 15:01

Lukas Kalbertodt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!