Skip to content

Commit 12404aa

Browse files
committed
auto merge of #9644 : alexcrichton/rust/clarify, r=huonw
It was a little ambiguous before how explicitl positional parameters and implicit positional parameters intermingled, and this clarifies how the two intermingle. This also updates a little bit of documentation/code examples elsewhere as well.
2 parents 0dce112 + 23cb72b commit 12404aa

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

src/libstd/fmt/mod.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ format!("The number is {:d}", 1) // => ~"The number is 1"
4040
format!("{:?}", ~[3, 4]) // => ~"~[3, 4]"
4141
format!("{value}", value=4) // => ~"4"
4242
format!("{} {}", 1, 2) // => ~"1 2"
43-
```
43+
```
4444
4545
From these, you can see that the first argument is a format string. It is
4646
required by the compiler for this to be a string literal; it cannot be a
@@ -56,6 +56,21 @@ example, the format string `{} {} {}` would take three parameters, and they
5656
would be formatted in the same order as they're given. The format string
5757
`{2} {1} {0}`, however, would format arguments in reverse order.
5858
59+
Things can get a little tricky once you start intermingling the two types of
60+
positional specifiers. The "next argument" specifier can be thought of as an
61+
iterator over the argument. Each time a "next argument" specifier is seen, the
62+
iterator advances. This leads to behavior like this:
63+
64+
```rust
65+
format!("{1} {} {0} {}", 1, 2) // => ~"2 1 1 2"
66+
```
67+
68+
The internal iterator over the argument has not been advanced by the time the
69+
first `{}` is seen, so it prints the first argument. Then upon reaching the
70+
second `{}`, the iterator has advanced forward to the second argument.
71+
Essentially, parameters which explicitly name their argument do not affect
72+
parameters which do not name an argument in terms of positional specifiers.
73+
5974
A format string is required to use all of its arguments, otherwise it is a
6075
compile-time error. You may refer to the same argument more than once in the
6176
format string, although it must always be referred to with the same type.
@@ -67,9 +82,17 @@ function, but the `format!` macro is a syntax extension which allows it to
6782
leverage named parameters. Named parameters are listed at the end of the
6883
argument list and have the syntax:
6984
70-
```
85+
```
7186
identifier '=' expression
72-
```
87+
```
88+
89+
For example, the following `format!` expressions all use named argument:
90+
91+
```rust
92+
format!("{argument}", argument = "test") // => ~"test"
93+
format!("{name} {}", 1, name = 2) // => ~"2 1"
94+
format!("{a:s} {c:d} {b:?}", a="a", b=(), c=3) // => ~"a 3 ()"
95+
```
7396
7497
It is illegal to put positional parameters (those without names) after arguments
7598
which have names. Like positional parameters, it is illegal to provided named
@@ -84,9 +107,9 @@ and if all references to one argument do not provide a type, then the format `?`
84107
is used (the type's rust-representation is printed). For example, this is an
85108
invalid format string:
86109
87-
```
110+
```
88111
{0:d} {0:s}
89-
```
112+
```
90113
91114
Because the first argument is both referred to as an integer as well as a
92115
string.
@@ -100,9 +123,9 @@ must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
100123
illegal to reference an argument as such. For example, this is another invalid
101124
format string:
102125
103-
```
126+
```
104127
{:.*s} {0:u}
105-
```
128+
```
106129
107130
### Formatting traits
108131
@@ -136,7 +159,7 @@ method of the signature:
136159
137160
```rust
138161
fn fmt(value: &T, f: &mut std::fmt::Formatter);
139-
```
162+
```
140163
141164
Your type will be passed by-reference in `value`, and then the function should
142165
emit output into the `f.buf` stream. It is up to each format trait
@@ -157,7 +180,7 @@ writeln! // same as write but appends a newline
157180
print! // the format string is printed to the standard output
158181
println! // same as print but appends a newline
159182
format_args! // described below.
160-
```
183+
```
161184
162185
163186
#### `write!`
@@ -172,7 +195,7 @@ use std::rt::io;
172195
173196
let mut w = io::mem::MemWriter::new();
174197
write!(&mut w as &mut io::Writer, "Hello {}!", "world");
175-
```
198+
```
176199
177200
#### `print!`
178201
@@ -183,7 +206,7 @@ output. Example usage is:
183206
```rust
184207
print!("Hello {}!", "world");
185208
println!("I have a newline {}", "character at the end");
186-
```
209+
```
187210
188211
#### `format_args!`
189212
This is a curious macro which is used to safely pass around
@@ -199,7 +222,7 @@ use std::fmt;
199222
format_args!(fmt::format, "this returns {}", "~str");
200223
format_args!(|args| { fmt::write(my_writer, args) }, "some {}", "args");
201224
format_args!(my_fn, "format {}", "string");
202-
```
225+
```
203226
204227
The first argument of the `format_args!` macro is a function (or closure) which
205228
takes one argument of type `&fmt::Arguments`. This structure can then be
@@ -238,7 +261,7 @@ example:
238261
239262
```rust
240263
format!("{0, select, other{#}}", "hello") // => ~"hello"
241-
```
264+
```
242265
243266
This example is the equivalent of `{0:s}` essentially.
244267
@@ -247,9 +270,9 @@ This example is the equivalent of `{0:s}` essentially.
247270
The select method is a switch over a `&str` parameter, and the parameter *must*
248271
be of the type `&str`. An example of the syntax is:
249272
250-
```
273+
```
251274
{0, select, male{...} female{...} other{...}}
252-
```
275+
```
253276
254277
Breaking this down, the `0`-th argument is selected upon with the `select`
255278
method, and then a number of cases follow. Each case is preceded by an
@@ -266,9 +289,9 @@ The plural method is a switch statement over a `uint` parameter, and the
266289
parameter *must* be a `uint`. A plural method in its full glory can be specified
267290
as:
268291
269-
```
292+
```
270293
{0, plural, offset=1 =1{...} two{...} many{...} other{...}}
271-
```
294+
```
272295
273296
To break this down, the first `0` indicates that this method is selecting over
274297
the value of the first positional parameter to the format string. Next, the
@@ -294,7 +317,7 @@ should not be too alien. Arguments are formatted with python-like syntax,
294317
meaning that arguments are surrounded by `{}` instead of the C-like `%`. The
295318
actual grammar for the formatting syntax is:
296319
297-
```
320+
```
298321
format_string := <text> [ format <text> ] *
299322
format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}'
300323
argument := integer | identifier
@@ -315,7 +338,7 @@ plural := 'plural' ',' [ 'offset:' integer ] ( selector arm ) *
315338
selector := '=' integer | keyword
316339
keyword := 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'
317340
arm := '{' format_string '}'
318-
```
341+
```
319342
320343
## Formatting Parameters
321344

0 commit comments

Comments
 (0)