Day 10e: String Formatting and Interpolation in Rust
Rust offers powerful and flexible string formatting capabilities through the format!
macro and the println!
macro. These macros allow developers to efficiently create strings that include embedded values, format numbers, control padding and alignment, and much more.
1. String Interpolation with the format!
Macro
The format!
macro is a versatile tool in Rust for string interpolation. It allows you to insert values into a string by using placeholders ({}
), which are replaced by variables or expressions at runtime. The macro returns the resulting string, which can be stored in a variable, passed to a function, or printed.
Basic Example of format!
for String Interpolation:
fn main() {
let name = "Alice";
let age = 30;
let message = format!("Hello, {}! You are {} years old.", name, age);
println!("{}", message); // Output: Hello, Alice! You are 30 years old.
}
Using Expressions Inside format!
:
fn main() {
let x = 5;
let y = 10;
let result = format!("{} + {} = {}", x, y, x + y);
println!("{}", result); // Output: 5 + 10 = 15
}
2. Formatting Numbers
Rust provides many options for formatting numbers in different bases or controlling their precision when working with floating-point values. The format!
macro supports formatting options for binary, hexadecimal, and decimal, among others.
2.1 Binary and Hexadecimal Formatting:
fn main() {
println!("{:b}", 10); // Output: 1010 (binary representation of 10)
println!("{:x}", 255); // Output: ff (hexadecimal representation of 255)
println!("{:o}", 8); // Output: 10 (octal representation of 8)
}
2.2 Floating-Point Formatting with Precision:
fn main() {
let pi = 3.14159;
println!("{:.2}", pi); // Output: 3.14 (two decimal places)
println!("{:.4}", pi); // Output: 3.1416 (four decimal places)
}
2.3 Padding and Alignment for Numbers:
fn main() {
println!("{:5}", 42); // Output: " 42" (right-aligned with spaces)
println!("{:05}", 42); // Output: "00042" (padded with zeros)
println!("{:<5}", 42); // Output: "42 " (left-aligned with spaces)
}
3. Advanced String Formatting
Rust’s format!
macro goes beyond basic interpolation and number formatting. It offers advanced options such as padding, alignment, and formatting complex data types.
3.1 Named Arguments in format!
:
fn main() {
let name = "Charlie";
let age = 28;
let location = "NYC";
println!("{name} is {age} years old and lives in {location}.", name = name, age = age, location = location);
}
3.2 Formatting Complex Data Types:
fn main() {
let tuple = (1, "Rust", 3.14);
println!("{:?}", tuple); // Output: (1, "Rust", 3.14)
}
You can also format a custom struct using Debug
or Display
by implementing these traits.
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 10, y: 20 };
println!("{:?}", point); // Output: Point { x: 10, y: 20 }
}
4. Direct Printing with the println!
Macro
The println!
macro is similar to format!
but prints the formatted string directly to the console instead of returning it. This is useful when you want to immediately display output rather than store it.
Example: Using println!
for Direct Output:
fn main() {
let name = "Bob";
println!("Hello, {}!", name); // Output: Hello, Bob!
}
Example: Combining Variables and Expressions:
fn main() {
let x = 3;
let y = 4;
println!("The sum of {} and {} is {}", x, y, x + y); // Output: The sum of 3 and 4 is 7
}
5. Debugging with {:?}
and {:#?}
When working with complex data structures or when debugging code, it’s often useful to see the internal representation of a value. The {:?}
and {:#?}
specifiers allow you to print the debug representation of values, with {:#?}
providing a more readable, pretty-printed version.
Example: Debug Printing:
fn main() {
let numbers = [1, 2, 3, 4];
println!("{:?}", numbers); // Output: [1, 2, 3, 4]
println!("{:#?}", numbers); // Pretty-printed output
}
Output using {:#?}
:
[
1,
2,
3,
4,
]
6. Special Formatting Options
In addition to number formatting and padding, Rust’s formatting system allows you to customize how booleans and characters are displayed.
Example: Formatting Booleans:
fn main() {
let is_rust_fun = true;
println!("Rust is fun: {}", is_rust_fun); // Output: Rust is fun: true
}
Example: Formatting Characters:
fn main() {
let letter = 'R';
println!("The first letter of Rust is: {}", letter); // Output: The first letter of Rust is: R
}
Conclusion
Rust’s format!
and println!
macros offer a rich set of features for formatting strings and numbers, giving you full control over how data is displayed in your applications. Whether you need basic string interpolation or advanced formatting for complex data types, these macros provide a clean and efficient way to generate strings.
format!
: Use for string interpolation and to create formatted strings that can be stored or passed as values.println!
: Use for direct output to the console, combining variables, expressions, and formatting options.- Number formatting: Use specifiers like
{:b}
,{:x}
,{:o}
, and{:.2}
for binary, hexadecimal, octal, and floating-point formatting. - Debug printing: Use
{:?}
or{:#?}
to inspect complex data structures in a readable format.