Just to clarify, the ..user1 syntax is not copy or clone, but move. The ownership is transferred. With bool or other primitive types, they implement Copy, which is why when transferring ownership, they clone their data instead of being moved
In Rust, you cannot transfer the ownership of something and automatically have it move back. It is always the responsibility of the owner to move itself to somewhere else.
In your code example, when you initialize user2, the ownership of username is transferred, so user1.username is no longer accessible. Thus from now on, you no longer have access to the entire user1, which is why you got the error value used here after partial move when trying to move its entirety to drop(). And it is now the responsibility of user2 to move the username it owns back to user1 before user2 is dropped.
If you want to temporarily let user2 have access to what user1 holds, what you need is borrow.
struct User {
active: bool,
username: String
}
fn main() {
let user1 = User {
active: true,
username: "someusername123".to_string(),
};
let user_ref = &user1; // user_ref borrows user1, but user1 still owns the data
drop(user_ref); // Here only the borrow is dropped
drop(user1); // Here the data is moved into drop()
}
If you also want to distinguish user_ref from user1, you can create a separate type that is a reference of User type
struct User {
active: bool,
username: String
}
struct UserRef<'a> {
active: bool,
username: &'a String,
}
impl User {
fn as_user_ref<'a>(&'a self) -> UserRef<'a> {
UserRef {
active: false,
username: &self.username,
}
}
}
fn main() {
let user1 = User {
active: true,
username: "someusername123".to_string(),
};
let user_ref = user1.as_user_ref(); // user_ref is type UserRef<'a>
drop(user_ref); // Here UserRef is dropped, but because it holds &String,
// nothing happens to the data
drop(user1); // Here the data is moved into drop()
}
Or if what you want is just to copy user1, and the two variables are not related, just derive the Clone trait.
#[derive(Clone)]
struct User {
active: bool,
username: String
}
impl User {
fn clone_inactive(&self) -> User {
let mut user = self.clone();
user.active = false;
user
}
}
fn main() {
let user1 = User {
active: true,
username: "someusername123".to_string(),
};
let user2 = user1.clone_inactive(); // user1 is cloned, there are now 2 String
drop(user2); // The String owned by user2 is dropped
drop(user1); // The String owned by user1 is dropped
}