Confused about Struct

the code is:

#[derive(Default, Debug)]
pub struct StructTest {
    a: u32,
    b: u32,
    c: Vec<u32>,
}
fn main(){
    let StructTest{a,..} = StructTest::default();
    println!{"{}",a};
}

question: so,are the following two ends of the code is equal?
A:

let StructTest{a,..} = StructTest::default();
println!{"{}",a};

B:

let st = StructTest::default();
let a=st.a;
println!{"{}",a};

i mean the question is ask for var "a".in the A,the "a" still can be println,and the value from StructTest::default()'s a.
thanks for the help.

Mostly. In the former case, the variables you don't bind will drop immediately. In the latter case, they will stick around until the end of their lexical scope.

The only difference is that in the first one the rest of the fields will be dropped before the rest of the code is run, whereas in the second one the rest of the fields will be dropped at the end of the scope. So for example if your StructTest contained a non-empty vector, with the first method its memory would be freed before you printed a whereas with the second method its memory would be freed after you printed a.

yes,the former case, the instance of struct will be drop immediately,but not the "a",the "println!("{}",a)" still can work.so ,i think maybe for "a" is let a = st.a;

yes,i know that,sorry maybe i unclear description the question,i mean the var "a",because of the println still can work,so,i guess maybe for the "a",the code is:let a = st.a; ?

Oh right - they will both print out the same value of a, which is 0.

yes,this kind of grammar not very much to can be meet in other crates(i mean about "a")?maybe my cognitive is right,but i wanna be sure about it

This is part of Rust's pattern matching capabilities, and applicable to more than just structs. See this section in the book.

But the comments about A dropping(never creating maybe??) a TestStruct and B creating both a TestStruct and then a from it are spot on. Does A actually initialize and drop a full instance of TestStruct? Or is the default passed directly to a?

1 Like

Semantically, it has to initialize and drop the full struct, but this might be elided by the optimizer if neither the construction nor the drop impl have any observable effects.

(Here's a playground where dropping prints.)

2 Likes

Ohh, neat. Good way to check on that. But does Droppy having drop effects make it so no level of optimization would elide away the creation/drop? Feels like I'm asking about Schrodinger's cat now...

Not that I have a use case for it, but is there a more direct way to access just a single field's default value?

At this point we might be picking on definitions. Certainly the semantics of the language don't permit the compiler to delete or move the println!() statement. But Droppy is zero-sized so probably no actual memory allocation is taking place anyway.

I wouldn't worry about the performance impact of this in any case.

2 Likes

Absolutely. Now it's just for scholarly interest at this point. Thanks for indulging my curiosity!

Not really, today. Maybe someday. You could follow some of the ideas in that thread, in many cases -- make some associated consts for your struct, which are individually available, and also use them to implement Default manually. But there's no built-in support for it currently.

However, if you just #[derive(Default)]'d, you could just use FieldType::default() since that's what the derived implementation does.

If you're worried about performance and not ergonomics, though...

...I agree with this. Default::default() is usually cheap and this use case is probably an easy target for the optimizer to boot.

2 Likes

i think it is a good way to understand this syntax.thanks

it's good way to prove the life cycle of TestStruct,thanks for help.

To expand on a earlier question, rust has to instantiate the whole struct, because you could have something like this:

impl Default for S {
    fn default()->S{
        let n = DateTime:: now();
        let a = n.month();
        S {
            n,
            a,
        }
    }
}

where there's no way to determine the value of a without running the default function.

In any case, the optimizer is free to remove anything it doesn't need, but you have to measure to know when that happens.

1 Like

i agree with u,thanks for reply,by the way,your picture of head is cool!