Invalidation of struct after moving one of its attributes

In the book it says

Note that the struct update syntax uses = like an assignment; this is because it moves the data, just as we saw in the “Ways Variables and Data Interact: Move” section. In this example, we can no longer use user1 after creating user2 because the String in the username field of user1 was moved into user2.

https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax

but it just works

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}


fn main() {
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    let user2 = User {
        active: user1.active,
        username: user1.username,
        email: String::from("another@example.com"),
        sign_in_count: user1.sign_in_count,
    };
    println!("{}, {}", user1.active, user2.active);
    println!("{}", user1.email);
}

the only problem is that you cant access user1.username anymore.
why book says like that?

1 Like

What you are seeing is the compiler tracking (at compile time) when each field in each variable is initialized, and because it can see that user1.email is still initialized, it's happy to let you print it.

On the other hand, because user1.username was moved and is now logically uninitialized, you can't change the second print statement to println!("{user1:?}") because that requires access to the full object. I think this latter point is what the book is trying to point out.

2 Likes

Note that you can't use user1 as a whole. For example &user1 or drop(user1) is not supposed to compile.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.