Rust中自定义struct无法实现居中打印?求原因与解决方案
问题原因及解决方法
问题原因
你当前的Display实现仅将struct转换为固定格式的字符串(例如<cheng-min, false>),使用{:^30}时,Rust会把这个完整字符串作为整体进行居中对齐,总宽度为30。如果你的预期是让struct的内部字段(name、sex)在30宽度内分别排版对齐,那当前实现无法满足——因为{:^30}的对齐作用对象是Display输出的最终字符串,而非结构体的单个字段。
另外,若你觉得输出未居中,也可能是对对齐逻辑的误解:最终居中后的总长度是30,包含字符串本身长度加上两侧填充的空格。比如<cheng-min, false>长度为18,两侧会各填充6个空格,总长度刚好30。
解决方法
根据你的实际需求,有两种处理方式:
1. 保持整体字符串居中(当前逻辑正确,验证预期)
如果你的需求就是让整个结构体的输出字符串在30宽度内居中,当前代码本身是正确的。你可以先打印字符串长度确认填充逻辑:
use std::fmt::{Display, Formatter}; struct sdt { name: String, sex: bool } impl Display for sdt { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "<{}, {}>", self.name, self.sex) } } fn main() { println!("{:^30}", "hello world!"); let s = sdt { name: String::from("cheng-min"), sex: false }; // 验证字符串长度 let s_output = format!("{}", s); println!("输出字符串长度: {}", s_output.len()); // 输出18 println!("{:^30}", s_output); // 和直接打印s效果一致,总宽度30 }
2. 自定义内部字段的30宽度排版(修改Display实现)
如果希望name和sex在30宽度内分别排版(比如分栏对齐),需要修改Display实现,利用Formatter提供的宽度参数:
use std::fmt::{Display, Formatter, Result}; struct sdt { name: String, sex: bool } impl Display for sdt { fn fmt(&self, f: &mut Formatter<'_>) -> Result { // 获取格式化时指定的宽度,默认使用30 let total_width = f.width().unwrap_or(30); // 分配name和sex的宽度,这里让name占大部分,sex右对齐 let name_width = total_width - 12; write!(f, "{:<name_width$} | {:>10}", self.name, self.sex, name_width = name_width) } } fn main() { println!("{:^30}", "hello world!"); let s = sdt { name: String::from("cheng-min"), sex: false }; // 直接打印就会按30宽度排版,也可以指定其他宽度如{:40} println!("{}", s); }
这段代码会让name左对齐占total_width-12的宽度,sex右对齐占10宽度,中间用|分隔,整体占满指定的宽度(默认30)。
内容的提问来源于stack exchange,提问作者cmtheit
相关产品推荐
相关产品推荐

