- handled by
std::fmt
- Supported the following macros:
format! write to String
print! and println! print to standard output io::stdout
eprint! and eprintln! print to standard error io::stderr
print! and eprint! do not call flush, need to call manually
write! and writeln! write to a &mut io::Write, returns Result<()>
format_args! customized format
Syntax
// general
println!("{variable}: {var:width$.precision$}");
// {} as placeholder
// Positional arguments {0}, {1}
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
// can have named arguments
// {key}
println!("{subject} {verb} {object}",
object="the lazy dog",
subject="the quick brown fox",
verb="jumps over");
// special foamtting using `:`
// {:b} for binary: output 10
println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
// width
// All of these print "Hello x !"
println!("Hello {:5}!", "x");
println!("Hello {:1$}!", "x", 5);
println!("Hello {1:0$}!", 5, "x");
println!("Hello {:width$}!", "x", width = 5);
// alignment using <, ^, or >
println!("{number:>width$}", number=1, width=6);
// padding
println!("{number:0>width$}", number=1, width=6);
// fill and alignment
assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
assert_eq!(format!("Hello {:-<5}!", "x"), "Hello x----!");
assert_eq!(format!("Hello {:^5}!", "x"), "Hello x !");
assert_eq!(format!("Hello {:>5}!", "x"), "Hello x!");
// alignment might not work for some types, particularly `Debug` trait
// `format` first
println!("Hello {:^15}!", format!("{:?}", Some("hi"))); // => "Hello Some("hi") !"
Precision
.N: the N is the precision
.N$
.*
// Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)}
println!("Hello {0} is {1:.5}", "x", 0.01);
// Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)}
println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
// Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
// Hello {next arg ("x")} is {second of next two args (0.01) with precision
// specified in first of next two args (5)}
println!("Hello {} is {:.*}", "x", 5, 0.01);
// Hello {next arg ("x")} is {arg 2 (0.01) with precision
// specified in its predecessor (5)}
println!("Hello {} is {2:.*}", "x", 5, 0.01);
// Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
// in arg "prec" (5)}
println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
// Hello, `1234.560` has 3 fractional digits
// Hello, `123` has 3 characters
// Hello, ` 123` has 3 right-aligned characters
- impl the following trait(s) to format as
{:*}
- nothing ⇒ Display
- ? ⇒ Debug
- x? ⇒ Debug with lower-case hexadecimal integers
- X? ⇒ Debug with upper-case hexadecimal integers
- o ⇒ Octal
- x ⇒ LowerHe
- X ⇒ UpperHex
- p ⇒ Pointer
- b ⇒ Binary
- e ⇒ LowerExp
- E ⇒ UpperExp
Debug Trait
- Derivable by
#[derive(Debug)]
- Use
{:?} or {:#?} for pretty print
- Can manually implement
fmt::Display too
// 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);
Display Trait
- use
{}
- Must implement manually
use std::fmt;
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)
}
}