为Vec <t>实现fmt :: Display

时间:2015-06-04 00:42:53

标签: printf rust traits

我想为我的代码中常用的嵌套结构实现fmt::Display

// The root structure
pub struct WhisperFile<'a> {
    pub path: &'a str,
    pub handle: RefCell<File>,
    pub header: Header
}

pub struct Header{
    pub metadata: metadata::Metadata,
    pub archive_infos: Vec<archive_info::ArchiveInfo>
}

pub struct Metadata {
   // SNIP
}

pub struct ArchiveInfo {
   // SNIP
}

如您所见,这是一个非平凡的数据树。 archive_infos上的Header属性在显示为一行时可能会很长。

我想发布一些符合

的内容
WhisperFile ({PATH})
  Metadata
    ...
  ArchiveInfo (0)
    ...
  ArchiveInfo (N)
    ...

但是当我尝试显示Vec<ArchiveInfo>时,我得到的显示没有实现。我可以为fmt::Display实施ArchiveInfo但由于fmt::Display没有为父容器Vec实施,因此还不够。如果我为collections::vec::Vec<ArchiveInfo>实现fmt :: Display,我会得到the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types

我已经尝试迭代vec并调用write!(),但我无法弄清楚控制流应该是什么样子。我认为write!()需要是函数的返回值,但是会因多次调用而失效。

我怎样才能打印出结构的Vec?

1 个答案:

答案 0 :(得分:6)

正如此错误所述,您无法为您不拥有的类型实施特征:

  

impl不引用此包中定义的任何类型;只有当前包中定义的特征才能实现任意类型

但是,您可以为包装类型实现Display。您缺少的部分是使用try!宏或try运算符?

use std::fmt;

struct Foo(Vec<u8>);

impl fmt::Display for Foo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Values:\n")?;
        for v in &self.0 {
            write!(f, "\t{}", v)?;
        }
        Ok(())
    }
}

fn main() {
    let f = Foo(vec![42]);
    println!("{}", f);
}