【发布时间】:2020-05-12 01:34:13
【问题描述】:
我有一个函数可以将我的 DocObj 呈现为 fmt::Write:
impl DocObj {
fn render(&self, write: &mut dyn Write) -> io::Result<()>;
}
为了实现fmt::Display,我想将相同的字节写入fmt::Formatter,而不需要复制和粘贴代码。
我是 rust 的新手,我尝试了各种解决方案,但到目前为止没有任何效果。
这是我尝试过的:
策略 1:为 std::Formatter 实现 Write 特征
失败是因为 rust 不允许我在另一个 crate 中实现一个类型的 trait。好的。
策略 2:为实现 Write 的 std::Formatter 创建一个小包装器
失败是因为我还不够了解生命周期或生锈。
struct DisplayWriter<'a> {
formatter: &'a fmt::Formatter<'a>
}
impl<'a> DisplayWriter<'a> {
fn from_formatter(aformatter: &'a mut fmt::Formatter<'a>) -> DisplayWriter<'a> {
DisplayWriter {formatter: aformatter}
}
}
impl<'a> io::Write for DisplayWriter<'a> {
fn write(&mut self, bytes: &[u8]) -> std::result::Result<usize, std::io::Error> {
use std::fmt::Write;
for c in bytes.iter() {
match self.formatter.write_char(*c as char) {
Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err))
}
}
Ok(bytes.len())
}
fn flush(&mut self) -> std::result::Result<(), std::io::Error> { todo!() }
}
impl fmt::Display for DocObj {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let write = DisplayWriter::from_formatter(f);
match self.render(&mut write) {
Ok(_) => Ok(()),
Err(err) => Err(fmt::Error)
}
}
}
使用此代码,编译器会报错:
error[E0623]: lifetime mismatch
--> src\cos.rs:286:51
|
285 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
| -------------------
| |
| these two types are declared with different lifetimes...
286 | let write = DisplayWriter::from_formatter(f);
| ^ ...but data from `f` flows into `f` here
关于我的上下文的一些说明:
- 我要显示的字节是不是 UTF-8 编码的。它们是二进制的。我想为每个字节显示一个字符。因此,任何进行 UTF 编码或解码的解决方案都不适用于我的上下文。
- 代码处于高性能循环中,因此我想避免分配内存。
感谢您的帮助!
【问题讨论】: