Rust Programming By Example
上QQ阅读APP看书,第一时间看更新

Creating structures

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/.