Rust by Example | страница 5



>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

One can manually implement fmt::Display to control the display.

fmt::Debug hardly looks compact and clean, so it is often advantageous to customize the output appearance. This is done by manually implementing fmt::Display, which uses the {} print marker. Implementing it looks like this:


>#![allow(unused)]

>fn main() {

>// Import (via `use`) the `fmt` module to make it available.

>use std::fmt;


>// Define a structure for which `fmt::Display` will be implemented. This is

>// a tuple struct named `Structure` that contains an `i32`.

>struct Structure(i32);


>// To use the `{}` marker, the trait `fmt::Display` must be implemented

>// manually for the type.

>impl fmt::Display for Structure {

>// This trait requires `fmt` with this exact signature.

>fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

>// Write strictly the first element into the supplied output

>// stream: `f`. Returns `fmt::Result` which indicates whether the

>// operation succeeded or failed. Note that `write!` uses syntax which

>// is very similar to `println!`.

>write!(f, "{}", self.0)

>}

>}

>}

fmt::Display may be cleaner than fmt::Debug but this presents a problem for the std library. How should ambiguous types be displayed? For example, if the std library implemented a single style for all Vec, what style should it be? Would it be either of these two?

   • Vec: /:/etc:/home/username:/bin (split on :)

   • Vec: 1,2,3 (split on ,)

No, because there is no ideal style for all types and the std library doesn't presume to dictate one. fmt::Display is not implemented for Vec or for any other generic containers. fmt::Debug must then be used for these generic cases.

This is not a problem though because for any new container type which is not generic,fmt::Display can be implemented.

>use std::fmt; // Import `fmt`

>// A structure holding two numbers. `Debug` will be derived so the results can

>// be contrasted with `Display`.

>#[derive(Debug)]

>struct MinMax(i64, i64);

>// Implement `Display` for `MinMax`.

>impl fmt::Display for MinMax {

>fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

>// Use `self.number` to refer to each positional data point.