9.3 Field Init Shorthand and Struct Update Syntax

Rust provides convenient syntax for initializing and updating structs.

9.3.1 Field Init Shorthand

If function parameters or local variables have the same names as struct fields, you can use a shorthand notation during instantiation.

struct User { active: bool, username: String, email: String, sign_in_count: u64 }
fn build_user(email: String, username: String) -> User {
    User {
        email, // Shorthand for email: email
        username, // Shorthand for username: username
        active: true,
        sign_in_count: 1,
    }
}

This reduces redundancy.

9.3.2 Struct Update Syntax

You can create a new struct instance using some explicitly specified fields and taking the rest from another instance using the .. syntax, which must appear last in the list of fields.

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
fn main() {
    let user1 = User {
        email: String::from("user1@example.com"),
        username: String::from("userone"),
        active: true,
        sign_in_count: 1,
    };

    let user2 = User {
        email: String::from("user2@example.com"),
        // `username`, `active`, `sign_in_count` will be taken from user1
        ..user1
    };

    println!("User 2 username: {}", user2.username);

    // Ownership consideration:
    // `email` was specified anew for `user2`.
    // Fields taken via `..user1` (`username`, `active`, `sign_in_count`) are
    // moved if they are not `Copy`, or copied if they are `Copy`.
    // Since `username` (String) is not Copy, it is moved from `user1`.
    // `active` (bool) and `sign_in_count` (u64) are Copy, so they are copied.
    // Therefore, `user1` is now partially moved.
    // println!("User 1 email: {}", user1.email); // OK: email was not moved
    // println!("User 1 active: {}", user1.active); // OK: active was copied
    // println!("User 1 username: {}", user1.username); Error! user1.username was moved
}

The struct update syntax moves or copies the remaining fields based on whether they implement the Copy trait.