Sometimes, we have multiple values that only make sense together, such as the two coordinates of a point. Structures are a way to create new types that contains multiple members.
Here is how we would create the aforementioned Point structure:
struct Point { x: i32, y: i32, }
To create a new point and access its members, we use the following syntax:
let point = Point { x: 24, y: 42, }; println!("({}, {})", point.x, point.y);
What if we want to print the point as a whole?
Let's try the following:
println!("{}", point);
The compiler does not accept this:
error[E0277]: the trait bound `Point: std::fmt::Display` is not satisfied --> src/main.rs:7:20 | 7 | println!("{}", point); | ^^^^^ `Point` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string | = help: the trait `std::fmt::Display` is not implemented for `Point` = note: required by `std::fmt::Display::fmt`
The {} syntax is used to display a value to the end user of the application. Nevertheless, there's no standard way to display arbitrary structures. We can do what the compiler suggests: using the {:?} syntax. That requires you to add an attribute to the structure, so let's change it:
#[derive(Debug)] struct Point { x: i32, y: i32, } println!("{:?}", point);
The #[derive(Debug)] attribute tells the compiler to automatically generate the code to be able to print a debug representation of the structure. We'll see how this works in the section about traits. It prints the following:
Point { x: 24, y: 42 }
Sometimes, the structure contains a lot of nested fields and this representation is hard to read. To remedy that, we can use the {:#?} syntax to pretty-print the value:
println!("{:#?}", point);
This gives the following output:
Point { x: 24, y: 42 }
The documentation describes what other formatting syntax can be used: https://doc.rust-lang.org/stable/std/fmt/.