打印Rust中的所有struct字段

时间:2019-10-23 02:56:40

标签: rust

我大约有10个结构,每个结构之间有5-10个字段,我希望能够使用相同的格式将它们打印出来。

我的大多数结构如下:

struct Example {
  a: Option<String>,
  b: Option<i64>,
  c: Option<String>,
  ... etc
}

我希望能够为impl定义一个fmt::Display,而不必再次枚举这些字段,因此,如果添加了新字段,就不会丢失该字段。

对于结构:

let eg = Example{
  a: Some("test".to_string),
  b: Some(123),
  c: None,
}

我想要输出格式:

a: test
b: 123
c: -

我当前正在使用#[derive(Debug)],但我不喜欢它打印出Some(X)None以及其他一些东西。

如果我知道结构中的所有值都是Option<T: fmt::Display>,是否可以自己生成Display方法而不必再次列出字段?

2 个答案:

答案 0 :(得分:5)

这可能不是最基本的实现,但是您可以派生可序列化并使用# A tibble: 13 x 6 dataset mean_x mean_y sd_x sd_y correlation <chr> <dbl> <dbl> <dbl> <dbl> <dbl> 1 away 54.3 47.8 16.8 26.9 -0.0641 2 bullseye 54.3 47.8 16.8 26.9 -0.0686 3 circle 54.3 47.8 16.8 26.9 -0.0683 4 dino 54.3 47.8 16.8 26.9 -0.0645 5 dots 54.3 47.8 16.8 26.9 -0.0603 6 h_lines 54.3 47.8 16.8 26.9 -0.0617 7 high_lines 54.3 47.8 16.8 26.9 -0.0685 8 slant_down 54.3 47.8 16.8 26.9 -0.0690 9 slant_up 54.3 47.8 16.8 26.9 -0.0686 10 star 54.3 47.8 16.8 26.9 -0.0630 11 v_lines 54.3 47.8 16.8 26.9 -0.0694 12 wide_lines 54.3 47.8 16.8 26.9 -0.0666 13 x_shape 54.3 47.8 16.8 26.9 -0.0656 条板箱。以下是自定义序列化程序的示例:https://serde.rs/impl-serializer.html

在您的情况下,它可能要简单得多(您只需要少数几种类型,就可以惊慌/忽略任何意外情况)。

另一种方法可能是编写宏并创建自己的轻量级序列化解决方案。

答案 1 :(得分:1)

我最终用一个宏解决了这个问题。虽然不理想,但可以胜任。

我的宏当前看起来像这样:

macro_rules! MyDisplay {
    ($struct:ident {$( $field:ident:$type:ty ),*,}) => {
        #[derive(Debug)]
        pub struct $struct { pub $($field: $type),*}

        impl fmt::Display for $struct {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                $(
                    write!(f, "{}: {}\n",
                        stringify!($field).to_string(),
                        match &self.$field {
                            None => "-".to_string(),
                            Some(x) => format!("{:#?}", x)
                        }
                    )?;
                )*
                Ok(())
            }
        }
    };
}

可以这样使用:

MyDisplay! {
    Example {
        a: Option<String>,
        b: Option<i64>,
        c: Option<String>,
    } 
}

一个带有示例的游乐场: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cc089f8aecaa04ce86f3f9e0307f8785

我的宏基于Cerberus在此处https://stackoverflow.com/a/54177889/1355121提供的宏