Format Strings in Rust
Rust has a family of macros, like println!
and format!
, that accept format strings. These are string literals that, at runtime, transform whatever is contained inside {}
.
They have their own grammar, which is worth taking a second to understand. So let’s print a bunch of strings.
Formatting with a type
In the above examples, we were implicitly using the Display
trait, but some types, like structs and vectors, don’t implement Display
.
We could implement Display
ourselves. In fact, this is a good way to go from an enum to a string in Rust.
Or, we could use a different trait, called Debug
.
The Display
trait is for user-facing output, and the Debug
trait is for programmer-facing output. Debug
is not unlike data classes in other languages.
In fact, if all the fields of the struct implement Debug
, we can automatically generate a Debug
implementation using the derive
attribute.
We have to also use the formatter ?
in the format string, to tell it to use the Debug
type instead of Display
.
Just like we switched the type to format with using the ?
formatter, we can do that for other types as well.
If you would like line breaks and indentation, you can pass the #
sign to the formatter. e.g. println!("{user:#?}");
.
What other cool things can you do with format strings?
Well, precision can be useful. For floating-point integers, it specifies the number of digits after the decimal point.
For a string, this means truncation.
Also, fill / alignment. This allows you to shift an arguments.
What macros take format strings?
Like I said, there’s a family of macros which take format strings.
format!
- return the formatted stringwrite!
- write the formatted string to the destination streamwriteln!
- same aswrite!
, but with a new lineprint!
- write the formatted string to standard outputprintln!
- same asprint!
but with a new lineeprint!
- write the formatted string to standard erroreprintln!
- same aseprint!
, but with a new lineformat_args!
- creates an intermediate type that can be passed to functions which accept format strings. This is useful if you’re creating your own function that you want to accept format strings. (see the next example)
Creating our own macro that takes a format string
Lastly, we’re going to implement our own macro, log!
, which takes a format string. Basically a simplified version of the log crate.
I learned a ton writing this, and I hope you learned something reading it. It’s possible, probable even, that something is wrong or suboptimal in this article. If you notice anything, please reach out.
Happy printing!
Wow! You read the whole thing. People who make it this far sometimes
want to receive emails when I post something new.
I also have an RSS feed.