So we’ve got ourselves a simply little struct
struct Point {
x: i32,
y: i32
}
We then decide that we’d like to output the current state of the Point using println!, so we write
fn main() {
let p = Point { x: 20, y: 3 };
println!("{}", p);
}
Running this will result in `Point` doesn’t implement `std::fmt::Display` and `Point` cannot be formatted with the default formatter. In fact we do not really need to implement std::fmt::Display, we can just annotate our struct with #[derive(Debug)] and then use the println! formatters (:? or :#?), for example
#[derive(Debug)]
struct Point {
x: i32,
y: i32
}
fn main() {
let p = Point { x: 20, y: 3 };
println!("{:?}", p);
}
The use of :? will result in the following output Point { x: 20, y: 3 } whereas :#? will display the values on lines of their own (a “prettier” formatter). Both :? and :#? are debug formatters, hence require the annotation #[derive(Debug)] or we can implement std::fmt::Debug, for example
impl std::fmt::Debug for Point {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "(x is {}, y is {})", self.x, self.y)
}
}
For situations where we simply want to create our own custom display (not just for Debug), then, as per the original error `Point` doesn’t implement `std::fmt::Display`, we would need to implement the std::fmt::Display trait, i.e.
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "(x is {}, y is {})", self.x, self.y)
}
}
This means we no longer requiring the annotation or special formatters, hence our full code will look like this
struct Point {
x: i32,
y: i32
}
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "(x is {}, y is {})", self.x, self.y)
}
}
fn main() {
let p = Point { x: 20, y: 3 };
println!("{}", p);
}
and as you’d expect our output is now (x is 20, y is 3).