The following code works
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32
}
fn area(shape: &Rectangle) -> u32 {
let Rectangle{width, height} = shape;
width * height
}
fn main() {
let rec1 = Rectangle {width: 5, height: 10};
println!("Area {}", area(&rec1));
println!("Rec {:?}", rec1);
}
But replacing the reference to struct &Shape with dereference reference *&Shape also works (e.g let Rectangle{width, height} = shape; --> let Rectangle{width, height} = *shape;).
I have no idea why both work, is there some implicit dereferencing when destructing? I though &Shape reference only points to where Shape is in memory, whereas *&Shape is Shape itself. width and height are properties of struct Rectangle rather than the reference &Rectangle.
I have no idea why both work, is there some implicit dereferencing when destructing?
This is a (convenient but confusing) consequence of Edition 2018's match ergonomics: when matching on reference types, the compiler will implicitly add references and deref so things are about right.
Here what happens in area is that width and height are &u32 not u32, the compiler effectively interprets your code as:
let &Rectangle{ ref width, ref height } = shape;
If you're not using something like rust-analyzer which can surface this information in your editor directly, a common trick is to write something like:
let x: () = var
the compilation error will tell you what the type of var is (unless it's ()).
I though &Shape reference only points to where Shape is in memory, whereas *&Shape is Shape itself.
That is true, however in the context of a pattern that doesn't necessarily mean the structure is moved. Here because the fields of Rectangle are both Copy the compiler can destructure the "owned" struct without needing to move it, it can just copy the fields. Which is essentially what a simple attribute access would do (shape.width is u32).
Actually, I have tried this in rust 2021, rust-analyzer told me, I get two reference: wdith and height. So I look at width * height line, there are two reference to u32, and * operator, aka std::ops::Mul have implement multipy of two &u32.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With