Reputation: 81
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);
Upvotes: 8
Views: 2740
Reputation: 431479
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 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);
Upvotes: 7