I'm going through Rust by Example and the use of $
(the dollar sign) in this example isn't clear to me:
// You can right-align text with a specified width. This will output
// " 1". 5 white spaces and a "1".
println!("{number:>width$}", number=1, width=6);
// You can pad numbers with extra zeroes. This will output "000001".
println!("{number:>0width$}", number=1, width=6);
I found this in the documentation for std::fmt
, but it doesn't clarify things for me:
format_string := <text> [ maybe-format <text> ] *
maybe-format := '{' '{' | '}' '}' | <format>
format := '{' [ argument ] [ ':' format_spec ] '}'
argument := integer | identifier
format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
fill := character
align := '<' | '^' | '>'
sign := '+' | '-'
width := count
precision := count | '*'
type := identifier | ''
count := parameter | integer
parameter := argument '$'
Poking around at the code a bit, I've found that it doesn't compile without the dollar sign, but "width
" can be replaced with any arbitrary identifier. i.e. the following is equivalent to the third line in the first code block:
println!("{number:>test$}", number=1, test=6);
The arguments of a macro are prefixed by a dollar sign $ and type annotated with a designator: macro_rules! create_function { // This macro takes an argument of designator `ident` and. // creates a function named `$func_name`.
Creates a String using interpolation of runtime expressions.
Functions. The format function takes an Arguments struct and returns the resulting formatted string. The write function takes an output stream, and an Arguments struct that can be precompiled with the format_args! macro.
It allows the width or precision of another formatted item to be provided as an argument instead of hard-coded as part of the format string. The parameter can be specified using a numeric index or a name.
The documentation says:
The value for the width can also be provided as a [
usize
] in the list of parameters by using the dollar syntax indicating that the second argument is a [usize
] specifying the width, for example:// All of these print "Hello x !" println!("Hello {:5}!", "x"); println!("Hello {:1$}!", "x", 5); println!("Hello {1:0$}!", 5, "x"); println!("Hello {:width$}!", "x", width = 5);
Referring to an argument with the dollar syntax does not affect the "next argument" counter, so it's usually a good idea to refer to arguments by position, or use named arguments.
It also says:
There are three possible ways to specify the desired
precision
:[...]
An integer or name followed by dollar sign
.N$
:use format argument
N
(which must be ausize
) as the precision.[...]
For example, the following calls all print the same thing
Hello x is 0.01000
:// Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)} println!("Hello {0} is {1:.5}", "x", 0.01); // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)} println!("Hello {1} is {2:.0$}", 5, "x", 0.01); // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)} println!("Hello {0} is {2:.1$}", "x", 5, 0.01); // Hello {next arg ("x")} is {second of next two args (0.01) with precision // specified in first of next two args (5)} println!("Hello {} is {:.*}", "x", 5, 0.01); // Hello {next arg ("x")} is {arg 2 (0.01) with precision // specified in its predecessor (5)} println!("Hello {} is {2:.*}", "x", 5, 0.01); // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified // in arg "prec" (5)} println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With