为Vec <T>实现fmt :: Display

xrl*_*xrl 5 printf traits rust

我想实现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
}
Run Code Online (Sandbox Code Playgroud)

如您所见,这是一个非平凡的数据树.当呈现为一行时,该archive_infos属性Header可以很长.

我想发布一些东西

WhisperFile ({PATH})
  Metadata
    ...
  ArchiveInfo (0)
    ...
  ArchiveInfo (N)
    ...
Run Code Online (Sandbox Code Playgroud)

但是当我尝试显示时,Vec<ArchiveInfo>我得到的显示没有实现.我可以实现fmt::Display,ArchiveInfo但这还不够,因为fmt::Display没有为父容器实现Vec.如果我实现FMT ::显示collections::vec::Vec<ArchiveInfo>我得到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?

She*_*ter 9

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • *impl没有引用此crate中定义的任何类型*=>仍然,在这种情况下,措辞令人困惑; `Vec <ArchiveInfo>`确实引用了此crate中定义的类型. (2认同)