Open
Description
Rust pattern matching and destructuring allows the use of &
and ref
.
In the example below, the use of these is intuitive.
fn main() {
let a: (u32) = (1234);
let (ref ref_a) = a;
let b: (&u32) = (&1234);
let (&deref_b) = b;
}
In this case, we end up with ref_a
of type &u32
, and deref_b
of type u32
. Simple enough -- we can go both ways with both ref
and &
in pattern matching.
In the instance with structs, this consistency breaks down when matching struct field names. In the example that follows, this is shown:
struct Borrowed {
val: u32
}
fn main() {
let a = Borrowed {
val: 1234
};
let Borrowed {ref val} = a;
}
In this case, val is borrowed as &u32
, mirroring tuple functionality. The following example on the other hand, does not work.
struct Derefed<'a> {
val: &'a u32
}
fn main() {
let a = Derefed {
val: &1234
};
let Derefed {&val} = a; // error: expected identifier, found `&`
let Derefed {val: &val} = a; // works as expected
}
While not functionality-breaking, it is extremely non-intuitive that this matching only works via ref
and not via &
for structs, when binding directly to the same variable name.