You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现fmt::Display的结构体格式化不遵循格式说明符怎么办?

问题:Rust自定义Display实现不遵循格式说明符的对齐规则

我编写了如下Rust代码:

use std::fmt;

struct MyStruct {
    mystring: String
}

impl fmt::Display for MyStruct {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "^.^ My String is *{}*. ^.^", self.mystring)
    }
}

fn main() {
    let mystruct = MyStruct { mystring: "GOAT".to_string() };
    println!("|{:^80}|", mystruct);
    println!("|{:^80}|", "^.^ My String is *GOAT*. ^.^")
}

期望MyStruct实例通过{:^80}格式说明符在80字符宽的字段中居中对齐,但实际输出并未生效,效果和直接使用{}一致:

|^.^ My String is *GOAT*. ^.^|
|                          ^.^ My String is *GOAT*. ^.^                          |

希望两行输出完全一致,请问如何修改格式化实现?


解决方案

问题根源

当前的fmt实现直接将字符串写入格式化器,绕过了Formatter内置的格式处理逻辑(包括对齐、宽度、填充等参数),导致{:^80}的设置被忽略。

修改后的实现

正确的做法是先构造原始显示内容,再调用Formatter的pad方法,让它处理对齐和宽度规则:

use std::fmt;

struct MyStruct {
    mystring: String
}

impl fmt::Display for MyStruct {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // 先构造原始显示内容
        let content = format!("^.^ My String is *{}*. ^.^", self.mystring);
        // 让Formatter应用格式说明符的规则(对齐、宽度等)
        f.pad(&content)
    }
}

fn main() {
    let mystruct = MyStruct { mystring: "GOAT".to_string() };
    println!("|{:^80}|", mystruct);
    println!("|{:^80}|", "^.^ My String is *GOAT*. ^.^")
}

更高效的写法(避免额外分配)

如果不想通过format!分配新字符串,可以用临时String写入内容后再调用pad:

impl fmt::Display for MyStruct {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut buf = String::new();
        write!(&mut buf, "^.^ My String is *{}*. ^.^", self.mystring)?;
        f.pad(&buf)
    }
}

运行结果

修改后两行输出完全一致:

|                          ^.^ My String is *GOAT*. ^.^                          |
|                          ^.^ My String is *GOAT*. ^.^                          |

内容的提问来源于stack exchange,提问作者MegaBrutal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:10:27