How to do printing with placeholders in Rust

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 placeholder
println!("Hello World!"); //Prints Hello World!
//With placeholder
println!("Hello {} {}!", "World", "2021");
//Prints Hello World 2021!
}

Display placeholder

The {} 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 placeholder

On 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 for Display print, and placeholder {:?} or {:#?} is used for Debug 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 parametersDisplay or Debug trait, alignment, padding, precision, etc. describe how the corresponding values would be converted to strings.

  • ? 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).

Printing with pretty-print

fn main() {
println!("{:#?}", vec!("Hello pretty_print!"));
println!();
//
println!("{:#?}", vec![Some("Hello"), None, Some("pretty_print!")]);
}

Code (printing with different placeholders)

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 World
println!();
// You can use named arguments with format
println!("{month} {year}", year="2021", month="December");
// Prints: 2021 December
println!();
// 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
}
Copyright ©2024 Educative, Inc. All rights reserved