Yes, these are the same to the compiler. In this case, there’s not much benefit. The real benefit comes from the match
equivalent:
fn func(data: &Foo) {
match data {
&Foo::One => {}
&Foo::Two => {}
&Foo::Three => {}
}
}
Here, you only have to place a single dereference, not 3 references in the patterns:
fn func(data: &Foo) {
match *data {
Foo::One => {}
Foo::Two => {}
Foo::Three => {}
}
}
And since Rust 1.26, you don’t even have to dereference the expression being matched on:
fn func(data: &Foo) {
match data {
Foo::One => {}
Foo::Two => {}
Foo::Three => {}
}
}
That’s why it’s the idiomatic choice.
The if let
concept is just an extension from this.
You can’t always dereference the value. If you tried to do the same thing for a pair of items:
fn func(data: &Foo, data2: &Foo) {
match (*data, *data2) {
(Foo::One, _) => {}
(Foo::Two, _) => {}
(Foo::Three, _) => {}
}
}
You get the error
error[E0507]: cannot move out of borrowed content
--> src/main.rs:8:12
|
8 | match (*data, *data2) {
| ^^^^^ cannot move out of borrowed content
In this case, you can use the reference form:
fn func(data: &Foo, data2: &Foo) {
match (data, data2) {
(&Foo::One, _) => {}
(&Foo::Two, _) => {}
(&Foo::Three, _) => {}
}
}
Or, since Rust 1.26, perform some implicit references:
fn func(data: &Foo, data2: &Foo) {
match (data, data2) {
(Foo::One, x) => {}
(Foo::Two, _) => {}
(Foo::Three, _) => {}
}
}