Rust uses println!
(and print!
) to produce and print text containing dynamic data. The first argument of println
is the format string that directs how the next arguments would be printed. This format string may include one or more placeholders.
println
allows us to print multiple variables using multiple placeholders.
fn main(){
let first_var = "John";
let second_var = "Doe";
println!("{} and {}", first_var, secod_var);
//first_var replaced with the first placeholder and the second_var with the second placeholder
}
//Output: John and Doe
The first placeholder, ({}
), is substituted with the first_var
, and the second placeholder, {}
, is substituted with the second_var
.
fn main() {//Without placeholderprintln!("Hello World!"); //Prints Hello World!//With placeholderprintln!("Hello {} {}!", "World", "2021");//Prints Hello World 2021!}
Display
placeholderThe {}
placeholder instructs the formatter to convert the value to text using the Display
trait. Display
formats the user-facing output. Rust data types, including numbers, strings, boolean, etc., implement the Display
trait.
Debug
placeholderOn the other hand, other types, including vectors (Vec<i32>
), Slices ([i32]
), and options Options<&str>
that do not have a clear user-facing representation of text, implement the Debug
trait.
According to the Debug documentation:
“Debug should format the output in a programmer-facing, debugging context.”
The Debug
trait formats the programmer-facing output, providing more information in a debugging context. As opposed to the Display
trait, Debug
uses the {:?}
placeholder.
In short, the placeholder
{}
is used forDisplay
print, and placeholder{:?}
or{:#?}
is used forDebug
print.
{:#?}
is a “pretty-print” placeholder and is similar to{:?}
, except that it prints output over more lines with a different format.
{:?}
and {:#?}
placeholders explained:
in the placeholder marks the beginning of a parameter list in an argument. The Display
or Debug
trait, alignment, padding, precision, etc.
?
in {:?}
is the formatting type that instructs the format!
family macro to assign printing to the Debug
trait.
#
in {:#?}
is the flag/modifier that indicates to use a different printing form. #?
instructs to use pretty-print (with indentation and linebreaks).
fn main() {println!("{:#?}", vec!("Hello pretty_print!"));println!();//println!("{:#?}", vec![Some("Hello"), None, Some("pretty_print!")]);}
fn main(){println!("{:?}", vec!["x", "y", "z"]); //debug placeholder// Prints: ["x", "y", "z"]println!();println!("{:?}", "HelloDebugPlaceholder"); //// Prints: "HelloDebugPlaceholder" (" " indicates a string was displayed)println!();println!("{:?}", Some("time"));// Prints: Some("time")println!();//The position of arguments is specified using numerical indexes.println!("{1} {2} {0}", "World", "My", "Hello" );// Prints: My Hello Worldprintln!();// You can use named arguments with formatprintln!("{month} {year}", year="2021", month="December");// Prints: 2021 Decemberprintln!();// We can even use Debug and Display prints together:println!("{language} {1:?}, {0}", "printing with placeholders", Some(101), language="Rust");//Prints: Rust Some(101), printing with placeholders}