学习Rust之打印输出 - mowatermelon/learn-rust GitHub Wiki

摘要

symbol mean
nothing Display
{:b} Binary
{:o} Octal
{:x?} Debug with lower-case hexadecimal integers
{:X?} Debug with upper-case hexadecimal integers
{:x} LowerHex
{:X} UpperHex
{:p} Pointer
{:e} LowerExp
{:E} UpperExp
{:?} Debug
{:#?} Pretty print Debug
{:#x} precedes the argument with a 0x
{:#X} precedes the argument with a 0X
{:#b} precedes the argument with a 0b
{:#o} precedes the argument with a 0o
{:.x?} sets the number of decimal places in floating-point types
{<arg>:<spec>.\*} the <arg> part refers to the value to print, and the precision must come in the input preceding <arg>.
{:number} use number defined minimum width
{:<} the argument is left-aligned in width columns
{:^} the argument is center-aligned in width columns
{:>} the argument is right-aligned in width columns
{:0} padding with 0

普通日志打印

重点语句

//1 -------- Do nothing before printing the information
print!("  print! {} days", 31);//  print! 31 days

//2 -------- Automatically wrap the line before printing the message
println!("  println! {} days", 31);//  println! 31 days

//3 -------- The location output can be specified by the location and name information of the parameter
println!("  println! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  println! Alice, this is Bob. Bob, this is Alice
println!("{subject} {verb} {object}",
            object="the lazy dog",
            subject="the quick brown fox",
            verb="jumps over");//the quick brown fox jumps over the lazy dog

//4 -------- Special formatting can be specified after a `:`.
println!("{} of {:b} people know binary, the other half doesn't", 1, 2);//1 of 10 people know binary, the other half doesn't

//5 -------- You can right-align text with a specified width. This will output
// "     1". 5 white spaces and a "1".
println!("{number:>width$}", number=1, width=6);//     1
// You can pad numbers with extra zeroes. This will output "000001".
println!("{number:>0width$}", number=1, width=6);//000001
// print!: same as format! but the text is printed to the console (io::stdout). some like console.log in js
// println!: same as print! but a newline is appended.

fn main() {
    // In general, the `{}` will be automatically replaced with any
    // arguments. These will be stringified.
    // format!("  format! {} days", 31);//  format! 31 days
    print!("  print! {} days", 31);//  print! 31 days
    println!("  println! {} days", 31);//  println! 31 days

    // Without a suffix, 31 becomes an i32. You can change what type 31 is,
    // with a suffix.

    // There are various optional patterns this works with. Positional
    // arguments can be used.
    // format!("  format! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  format! Alice, this is Bob. Bob, this is Alice
    print!("  print! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  print! Alice, this is Bob. Bob, this is Alice
    println!("  println! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  println! Alice, this is Bob. Bob, this is Alice

    // As can named arguments.
    println!("{subject} {verb} {object}",
             object="the lazy dog",
             subject="the quick brown fox",
             verb="jumps over");//the quick brown fox jumps over the lazy dog

    // Special formatting can be specified after a `:`.
    println!("{} of {:b} people know binary, the other half doesn't", 1, 2);//1 of 10 people know binary, the other half doesn't

    // You can right-align text with a specified width. This will output
    // "     1". 5 white spaces and a "1".
    println!("{number:>width$}", number=1, width=6);//     1

    // You can pad numbers with extra zeroes. This will output "000001".
    println!("{number:>0width$}", number=1, width=6);//000001

    // It will even check to make sure the correct number of arguments are
    // used.
    // println!("My name is {0}, {1} {0}", "Bond");
    // Run it. See? Now try deleting the two slashes, and run it again.
    // |                               ^^^
    // |
    // = note: positional arguments are zero-based
}

普通错误打印

重点语句

//Do nothing before printing the information
eprint!("  eprint! {} days", 31);//  eprint! 31 days

//Automatically wrap the line before printing the message
eprintln!("  eprintln! {} days", 31);//  eprintln! 31 days

//Other features are consistent with print
// eprint!: same as format! but the text is printed to the standard error (io::stderr). some like console.error in js
// eprintln!: sames as eprint!but a newline is appended.
fn main() {
    // In general, the `{}` will be automatically replaced with any
    // arguments. These will be stringified.
    eprint!("  eprint! {} days", 31);//  eprint! 31 days
    eprintln!("  eprintln! {} days", 31);//  eprintln! 31 days

    eprint!("  eprint! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  eprint! Alice, this is Bob. Bob, this is Alice
    eprintln!("  eprintln! {0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//  eprintln! Alice, this is Bob. Bob, this is Alice
}

自定义类型打印

简单打印

重点语句

// step 1 : use std::fmt
use std::fmt; // Import `fmt`

// step 2 : declared a custom structure
struct MinMax(i64, i64);

// step 3 : Print functions are implemented through `fmt::Display`
impl fmt::Display for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Use `self.number` to refer to each positional data point.
        write!(f, "({}, {})", self.0, self.1)
    }
}

impl fmt::Binary for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Use `self.number` to refer to each positional data point.
        write!(f, "Binary ({}, {})", self.0, self.1)
    }
}

//step 4 :use {} or {:b} in println!
println!("Display: {}", minmax); //Display: (0, 14)
println!("What does minmax look like in binary: {:b}?", minmax);//What does minmax look like in binary: Binary (0, 14)?
// if not use ,it will failed to resolve. and see message,use of undeclared type or module `fmt`
use std::fmt; // Import `fmt`

// is a structure which contains two `i64`
struct MinMax(i64, i64);

// Implement `Display` for `MinMax`.so that MinMax can use normal print {}
// if not inheritance , `MinMax` cannot be formatted with the default formatter
impl fmt::Display for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Use `self.number` to refer to each positional data point.
        write!(f, "({}, {})", self.0, self.1)
    }
}

// Implement `Binary` for `MinMax`.
impl fmt::Binary for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Use `self.number` to refer to each positional data point.
        write!(f, "Binary ({}, {})", self.0, self.1)
    }
}

// Define a structure where the fields are nameable for comparison.
struct Point2D {
    x: f64,
    y: f64,
}

// Similarly, implement for Point2D
// so that Point2D can use normal print {}
impl fmt::Display for Point2D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Customize so only `x` and `y` are denoted.
        write!(f, "x: {}, y: {}", self.x, self.y)
    }
}

fn main() {
    let minmax = MinMax(0, 14);

    println!("Compare structures:"); //Compare structures:
    println!("Display: {}", minmax); //Display: (0, 14)
    println!("What does minmax look like in binary: {:b}?", minmax);//What does minmax look like in binary: Binary (0, 14)?

    let big_range = MinMax(-300, 300);
    let small_range = MinMax(-3, 3);

    //if the trait `std::fmt::Display` is not implemented for `MinMax`,
    //small can not equal small_range,
    //big can not equal big_range,
    println!(
        "The big range is {big} and the small is {small}",
        small = small_range,
        big = big_range
    ); //The big range is (-300, 300) and the small is (-3, 3)

    let point = Point2D { x: 3.3, y: 7.2 }; //The big range is (-300, 300) and the small is (-3, 3)

    println!("Compare points:"); //Compare points:
    println!("Display: {}", point); //Display: x: 3.3, y: 7.2

    // println!("What does Point2D look like in binary: {:b}?", point);
    //     error[E0277]: the trait bound `Point2D: std::fmt::Binary` is not satisfied
    //   --> example05-display.rs:53:62
    //    |
    // 63 |     println!("What does Point2D look like in binary: {:b}?", point);
    //    |                                                              ^^^^^ the trait `std::fmt::Binary` is not implemented for `Point2D`
    //    |
    //    = note: required by `std::fmt::Binary::fmt`
}

复杂打印

重点语句

// step 1: Statement using `Debug` trait.
// Derive the `fmt::Debug` implementation for `Structure`. `Structure`
// step 2 : declared a custom structure
// Note that there is no line breaks between the two statements
#[derive(Debug)]
struct Structure(i32);
// Derive the `fmt::Debug` implementation for `Structure`. `Structure`
// is a structure which contains a single `i32`.
#[derive(Debug)]
struct Structure(i32);

// Put a `Structure` inside of the structure `Deep`. Make it printable
// also.
#[derive(Debug)]
struct Deep(Structure);

fn main() {
    // Printing with `{:?}` is similar to with `{}`.
    println!("{:?} months in a year.", 12);//12 months in a year.
    println!("{1:?} {0:?} is the {actor:?} name.",
             "Slater",
             "Christian",
             actor="actor's");//"Christian" "Slater" is the "actor\'s" name.

    // `Structure` is printable!
    println!("Now {:?} will print!", Structure(3));//Now Structure(3) will print!

    // The problem with `derive` is there is no control over how
    // the results look. What if I want this to just show a `7`?
    println!("Now {:?} will print!", Deep(Structure(7)));//Now Deep(Structure(7)) will print!
}

打印优化

重点语句

// step 1: Statement using `Debug` trait.
// Derive the `fmt::Debug` implementation for `Structure`. `Structure`
// step 2 : declared a custom structure
// Note that there is no line breaks between the two statements
#[derive(Debug)]
struct Structure<'a> (&'a str);

//step 3 :instantiated object
let sex = Structure("girl");

//step 4 :use {:#?} in println!,Pretty print!!!
println!("{:#?}", sex);
//Structure(
//  "girl"
// )
//
// All std library types automatically are printable with {:?} and {:#?}:
// But the user's custom structure requires explicit declarations that require `std::fmt::Debug` trait
#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8,
}

#[derive(Debug)]
struct Structure<'a> (&'a str);

fn main() {

    let sex = Structure("girl");

    // normal print
    println!("{:?}", sex); //Structure("girl")

    // Pretty print
    println!("{:#?}", sex);
    //Structure(
    //  "girl"
    // )
    //

    let name = "Melon";
    let age = 18;

    let melon = Person { name, age };//same as let melon = Person { "name":name, "age": age };

    // normal print
    println!("{:?}", melon); //Person { name: "Melon", age: 18 }

    // Pretty print
    println!("{:#?}", melon);
    //Person {
    //  name: "Melon",
    //  age: 18
    //}
}

打印 Vec

重点语句

// step 1 : use std::fmt
use std::fmt; // Import `fmt`

// step 2 : declared a custom structure
struct Water(Vec<i64>);

// step 3 : Print functions are implemented through `fmt::Display`
impl fmt::Display for Water {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let vec = &self.0;
        write!(f, "[")?;
        for (index, item) in vec.iter().enumerate() {
            if index != 0 {
                write!(f, ",")?;
            }
            write!(f, "{{ index : {} ,value : {} }}", index, item)?;
        }
        write!(f, "]")
    }
}

//step 4 :Instantiate an Water object
let temp_arr = Water(vec![1, 2, 3]);

//step 5 :use {} in println!
println!("{}", temp_arr);//[{ index : 0 ,value : 1 },{ index : 1 ,value : 2 },{ index : 2 ,value : 3 }]
// if not use ,it will failed to resolve. and see message,use of undeclared type or module `fmt`
// note that there are no double quotes between use and std
// not use::std::fmt;
// Also, be sure to add a semicolon at the end of the statement
use std::fmt;

// Define a structure named `List` containing a `Vec`.
// Note that the data type of the child variable
// is declared using an Angle, not parentheses
// not struct Water(Vec(i64));
struct Water(Vec<i64>);

impl fmt::Display for Water {
    // All objects except the first default private object
    // need to be declared before being used
    // like : variable name: variable value
    // example of the error : fmt(&self,f: fn &mut fmt::Formatter)

    // declare the return result type to use ::
    // example of the error :  -> fmt Result

    // note that there is a space before the curly braces are written,
    // otherwise you will get a compile error
    // note that you need to use the `&mut` here or you won't get the value of `f` in the current range
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Extract the value using tuple indexing
        // and create a reference to `vec`.
        let vec = &self.0;
        // Implementing fmt::Display for a structure 
        // where the elements must each be handled sequentially is tricky. 
        // The problem is that each write! generates a `fmt::Result`. 
        // Proper handling of this requires dealing with all the results. 
        // Rust provides the ? operator for exactly this purpose.

        // Note that the write is followed by an `!` mark,
        // which represents the macro command being executed
        write!(f, "[")?;

        // Iterate over `vec` in `v` while enumerating the iteration

        // the name of the method used by the iterator is iter
        // example of the error : vec.itev()

        // the name of the method calling the enumeration is enumerate
        // example of the error : vec.iter().enum()
        for (index, item) in vec.iter().enumerate() {
            if index != 0 {
                write!(f, ",")?;
            }
            // mainly if you want to use {as an auxiliary symbol in formatting,
            // note that you need to write it twice,like `{{` and `}}`
            write!(f, "{{ index : {} ,value : {} }}", index, item)?;
        }

        // Note that the last statement does not end with a semicolon,
        // or a compilation error will occur

        // Notice also that the last write method ends without adding, okay?
        write!(f, "]")
    }
}

fn main() {
    // the structure initialization of an array object must be consistent with the type in the structure
    // example of the error : Water([1,2,3])

    // the struct initialization of an array object is done inside ()
    // example of the error : Water[vec![1,2,3]]

    // Note that the `vec` is followed by an `!` mark,
    // which represents the macro command being executed
    let temp_arr = Water(vec![1, 2, 3]);
    println!("{}", temp_arr);//[{ index : 0 ,value : 1 },{ index : 1 ,value : 2 },{ index : 2 ,value : 3 }]
}
⚠️ **GitHub.com Fallback** ⚠️