实现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
相关产品推荐
相关产品推荐

