Inspecting println!
- Rust course
- Advanced
- Lesson 46/81
- 4 min
Inspect the internals of the println! macro.
Inside println!
println! is a macro because it checks the format string at compile time: if the number of placeholders and arguments doesn't match, it's a compile error. It expands roughly like this:
println!("x = {}", 5);
// expansion (simplified):
::std::io::_print(format_args!("x = {}\n", 5));format_args! is a macro built into the compiler; it parses the format and produces a fmt::Arguments value without allocating. format!, write! and panic! use the same foundation.
Your own format macro
To forward arguments as they are, a tt repetition is used; this way the macro supports all of println!'s forms. stringify! gives an expression as its source text:
macro_rules! kayit {
($($arg:tt)*) => {
println!("[log] {}", format!($($arg)*))
};
}
macro_rules! goster {
($e:expr) => {
println!("{} = {:?}", stringify!($e), $e)
};
}
kayit!("x = {}", 5); // [log] x = 5
goster!(2 + 3); // 2 + 3 = 5The dbg! macro is built on exactly this idea.
Practice Logging macros
Write the kayit! and goster! macros above. Make the calls kayit!("x = {}", 5) and goster!(2 + 3).
Starter code
fn main() {
// buraya yaz
}Sample solution
macro_rules! kayit {
($($arg:tt)*) => {
println!("[log] {}", format!($($arg)*))
};
}
macro_rules! goster {
($e:expr) => {
println!("{} = {:?}", stringify!($e), $e)
};
}
fn main() {
kayit!("x = {}", 5);
goster!(2 + 3);
}Expected output
[log] x = 5 2 + 3 = 5
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What happens with <code>println!("{} {}", 1)</code>?
- It prints "1 "
- Panic
- It prints "1 {}"
- Compile error: 2 placeholders, 1 argument Correct answer
Explanation: The format string must be a literal; that's how the compiler can parse and check it.
2 Source text
println!("{} = {:?}", ____!($e), $e)
println!("{} = {:?}", stringify!($e), $e)
Explanation: stringify! gives a piece of code as text.
3 Macro and job
| Term | Meaning |
|---|---|
format_args! |
Format without allocating |
format! |
Produces a String |
stringify! |
Turns code into text |
dbg! |
Prints expression and value |