Noldorin Zhang
Noldorin Zhang

Reputation: 321

Is `String` truly a reference type in Rust?

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

fn main() {
    let mut user = User {
        username: String::from("Paulx"),
        email: String::from("[email protected]"),
        sign_in_count: 0,
        active: true,
    };

    let name = user.username;
    user.username = String::from("Alix");

    println!("{}", name);
}

You will see that the username is copied from user the the variable name. The variable name is not scalar type, why can it make this copy?

Upvotes: 0

Views: 136

Answers (1)

Finomnis
Finomnis

Reputation: 22868

I think there is a misunderstanding here.

You did not copy the user.username, you moved it out.

Until you assign a new user.username, the entry user.username is invalid.

See here:

struct User {
    username: String,
}

fn main() {
    let mut user = User {
        username: String::from("Paulx"),
    };

    let name = user.username;

    // Fails to compile!
    println!("{}", user.username);

    user.username = String::from("Alix");

    // Works again.
    println!("{}", user.username);

    println!("{}", name);
}
error[E0382]: borrow of moved value: `user.username`
  --> src/main.rs:13:20
   |
10 |     let name = user.username;
   |                ------------- value moved here
...
13 |     println!("{}", user.username);
   |                    ^^^^^^^^^^^^^ value borrowed here after move
   |
   = note: move occurs because `user.username` has type `String`, which does not implement the `Copy` trait
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

Upvotes: 5

Related Questions