我想编写一个产生一些文本的函数,例如:
fn produce_stuff(/* ??? */) -> Result<()> {
write!(...);
write!(...);
write!(...);
...
}
我希望能够在两个上下文中使用此功能:
- 使用它输出到IO作者 - 像
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!
是在这两种情况下都起作用的宏(,但是为此使用宏是一种错误的。
您只需要实现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)
调用call效率。
游乐场