我想编写一个生成一些文本的函数,如下所示:
fn produce_stuff(/* ??? */) -> Result<()> {
write!(...);
write!(...);
write!(...);
...
}
我希望能够在两种情况下使用此功能:
produce_text(io.stdout())
。Display
时将其用作辅助函数,如下所示:struct Foo { ... }
impl Display for Foo {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
...
produce_text(f);
...
}
}
似乎每个用例都需要produce_text
使用不同的签名。对于#1,该函数需要采用实现std::io::Write
的东西,对于#2,则需要采用std::fmt::Formatter
。
我想我可以将其写为宏而不是函数(类似于write!
是在两种情况下都可以工作的宏),但是为此使用宏有点不妥。 / p>
答案 0 :(得分:5)
您只需要实现Display
。
当Foo
实现Display
时,您可以将其与Write
的任何实现一起使用,包括io::Stdout
:
use std::{
io::{self, Write},
fmt,
};
struct Foo {
field: u16,
}
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Foo({})", self.field)
}
}
fn main() {
write!(io::stdout(), "{}", Foo{field: 3}).unwrap();
}
您不必编写自己的宏;只需使用write!
。这应该不会错,这是正常的方法。
与"{}"
参数无关的运行时成本:它是在编译时(在内置的编译器中)进行解析的,这使write!(w, "{}", displayable)
的调用效率很高。