5.1. Defining and Instantiating Structs

Struct update syntax

Using struct update syntax, we can achieve the same effect with less code, as shown below. The syntax .. specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance.

fn main() {
    // --snip--

    let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };
}

Note that in above example, if any field of user1 is directly used as user2 ’s field (no updates) and the type of it does not implement Copy trait, user1 will be invalid because it’s moved into user2 .

Tuple struct

To define a tuple struct, start with the struct keyword and the struct name followed by the types in the tuple. For example, here we define and use two tuple structs named Color and Point:

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
}

Unit-like struct

Unit-like structs can be useful when you need to implement a trait on some type but don’t have any data that you want to store in the type itself.

struct AlwaysEqual;

fn main() {
    let subject = AlwaysEqual;
}

The dbg! macro for debugging

dbg! takes ownership of an expression, prints the file and line number of where that macro call occurs in your code along with the resulting value of that expression, and returns ownership of the value.

Here’s an example where we’re interested in the value that gets assigned to the width field, as well as the value of the whole struct in rect1:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let scale = 2;
    let rect1 = Rectangle {
        width: dbg!(30 * scale),
        height: 50,
    };

    dbg!(&rect1);
}

Here’s what the output of this example looks like:

$ cargo run
   Compiling rectangles v0.1.0 (file:///projects/rectangles)
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s
     Running `target/debug/rectangles`
[src/main.rs:10] 30 * scale = 60
[src/main.rs:14] &rect1 = Rectangle {
    width: 60,
    height: 50,
}