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
.
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 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;
}
dbg!
macro for debuggingdbg!
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,
}