问题
I wanted to imitate Python's rjust
, ljust
, and center
functions using the format!
macro, but I was only able to work out a solution where you can pass in the string and the width. If you want to pass in the fill-argument it doesn't work.
The documentation tells me that it is possible to provide variables to format!
and for the width argument it works just fine. When I try to use a variable for fill, the compiler does not recognize the pattern.
Just the width as a variable works:
fn rjust(text: &str, width: usize, fill: Option<char>) -> String {
format!("{text:>width$}", text = text, width = width)
}
println!("{}", rjust("Hello", 10)); // " Hello"
Providing the fill as a variable does not work:
fn rjust(text: &str, width: usize, fill: char) -> String {
format!(
"{text:fill>width$}",
text = text,
fill = fill,
width = width
)
}
println!("{}", rjust("Hello", 20, '*'));
The error message:
error: invalid format string: expected `'}'`, found `'>'`
--> src/lib.rs:4:24
|
4 | "{text:fill>width$}",
| - ^ expected `}` in format string
| |
| because of this opening brace
|
= note: if you intended to print `{`, you can escape it using `{{`
If I provide a single character instead of the fill-variable, it works fine. Notice the *
character:
fn rjust(text: &str, width: usize, fill: char) -> String {
format!("{text:*>width$}", text = text, width = width)
}
println!("{}", rjust("Hello", 20, '_')); // ***************Hello
I expected the fill-variable version to work the same as the hardcoded *
character version.
A workaround is to subtract the length of the text from the width and then create a String
of that length (fill-length) made of fill-characters and concatenate them:
fn rjust(text: &str, width: usize, fill: char) -> String {
let fill_len = width - text.len();
let fill_str: String = (0..fill_len).map(|_| fill).collect();
String::from(fill_str + text)
}
println!("{}", rjust("Hello", 20, '*')); // ***************Hello
回答1:
Unfortunately there is no built-in way to do this.
The formatting syntax evolved with features that early Rust adopters needed at the time. Its terseness means that new features are very difficult to add after the fact.
来源:https://stackoverflow.com/questions/56666258/is-it-possible-to-use-a-variable-as-the-fill-argument-in-the-format-macro