Rust中如何自定义结构体格式化输出以实现预期样式?
自定义Rust结构体的Display格式化输出以匹配预期样式
问题场景
你尝试通过Debug trait的#?修饰符实现结构体的格式化输出,但结果不符合预期,需要调整代码来达到目标样式。
原代码
#[derive(Debug)] struct Point { x: i32, y: i32, } #[derive(Debug)] struct Foo { point: Point } impl fmt::Display for Foo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "({:#?})", self) } } const origin: Point = Point { x: 0, y: 0 }; const foo: Foo = Foo { point: origin}; println!("{}", foo);
当前输出
(Foo { point: Point { x: 0, y: 0, }, })
期望输出
Foo { point: Point {x: 0, y: 0} }
解决方案
要实现目标样式,不能直接复用Debug的格式化逻辑,需要手动控制每一部分的输出格式。以下提供两种可行方案:
方案一:给Point单独实现Display(推荐)
通过给Point实现Display来复用紧凑格式的逻辑,再在Foo的Display中控制整体的换行与缩进:
use std::fmt; #[derive(Debug)] struct Point { x: i32, y: i32, } #[derive(Debug)] struct Foo { point: Point } impl fmt::Display for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Point {{x: {}, y: {}}}", self.x, self.y) } } impl fmt::Display for Foo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Foo {{")?; writeln!(f, " point: {}", self.point)?; write!(f, "}}") } } const origin: Point = Point { x: 0, y: 0 }; const foo: Foo = Foo { point: origin}; fn main() { println!("{}", foo); }
方案二:直接在Foo的Display中硬编码Point格式
如果不需要给Point单独实现Display,可以直接在Foo的格式化逻辑中处理Point的输出:
use std::fmt; #[derive(Debug)] struct Point { x: i32, y: i32, } #[derive(Debug)] struct Foo { point: Point } impl fmt::Display for Foo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Foo {{")?; writeln!(f, " point: Point {{x: {}, y: {}}}", self.point.x, self.point.y)?; write!(f, "}}") } } const origin: Point = Point { x: 0, y: 0 }; const foo: Foo = Foo { point: origin}; fn main() { println!("{}", foo); }
两种方案执行后都会输出你期望的样式:
Foo { point: Point {x: 0, y: 0} }
内容的提问来源于stack exchange,提问作者navier stokes
相关产品推荐
相关产品推荐

