使用println打印一个字符多次的变量

14

我想使用println!format!强大的格式化工具来打印一个特定次数的字符。当然,这可以通过循环实现,代码如下:

fn give_love(count: usize) {
    print!("Here is love for you: ");
    for i in 0..count {
        print!("♥");
    }
    println!("");
}

但我既不想编写循环,也不想编写三个 print 语句。如何更短、更好地实现?

3个回答

33

您代码的解决方案

fn give_love(count: usize) {
    println!("Here is love for you: {:♥<1$}", "", count);
}

解释

您可以(误用)使用填充功能,该功能允许使用您选择的某个字符填充打印值。仅针对此功能的语法如下:


'{' ':' <fill> <align> <width> '}'

其中,width 可以是一个常数或者是类型为 <argument_index> '$' 的参数引用。因此,3 表示宽度为 3,而 1$ 表示宽度为 println! 的第一个参数的值。


然而,在这里我们有点“滥用”了这个特性,我们不能忘记我们只是为其他可打印的东西指定“填充”,这些可打印的东西将作为参数传递给 println。这个可打印的东西可能是一个空字符串。

println!("love: {:♥<3}", "");     // love: ♥♥♥
println!("love: {:♥<1$}", "", 5); // love: ♥♥♥♥♥

以下是一些我们不传递空字符串的例子:

println!("love: {:♥<5}", "#");    // love: #♥♥♥♥
println!("love: {:♥>5}", "#");    // love: ♥♥♥♥#
println!("love: {:♥^5}", "#");    // love: ♥♥#♥♥

5
或者(提及一个不太聪明的替代方案),你可以使用repeat('♥').take(count).collect::<String>()来重复生成心形符号并收集成一个字符串。 - Paolo Falabella

5
自1.16版本开始,您可以像这样使用.repeat()
fn main() {
    println!("Here is love for you: {}", "♥".repeat(10));
}

playground link


1
请注意,与其他两个答案不同,这里分配了一个String。尽管如此,在大多数情况下,这种小的开销可能并不重要,因此它是一个完全可以接受的解决方案。 - Lukas Kalbertodt

5
如果您想要以更简洁的方式重复任何Displayable项目而不创建中间分配,您可以创建一个包装结构体并编写自定义的Display实现以执行重复:
use std::fmt::{self, Display};

#[derive(Clone, Copy)]
struct DisplayRepeat<T>(usize, T);

impl<T: Display> Display for DisplayRepeat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for _ in 0..self.0 {
            self.1.fmt(f)?;
        }
        Ok(())
    }
}

fn repeat<T>(times: usize, item: T) -> DisplayRepeat<T> {
    DisplayRepeat(times, item)
}

fn main() {
    println!("Here is love for you: {}", repeat(10, '♥'));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接