【问题标题】:How to make a public struct where all fields are public without repeating `pub` for every field?如何制作一个所有字段都是公共的公共结构而不为每个字段重复“pub”?
【发布时间】:2019-05-20 20:19:59
【问题描述】:

如何在 Rust 中定义一个公共结构,其中所有字段都是公共的,而不必在每个字段前重复 pub 修饰符?

pub_struct 宏将是理想的:

pub_struct! Foo {
    a: i32,
    b: f64,
    // ...
}

相当于:

pub struct Foo {
    pub a: i32,
    pub b: f64,
    //...
}

【问题讨论】:

  • 让我们明确一点:你想要一个没有第一列精确的结构声明 public ?宏可能可以插入这些修饰符,但您代码的其他读者必须学习您自己的特殊语法才能理解整个是公共的......
  • 所以pub Foo { pub a: u32, pub b: u32 } 不是您要找的?
  • 你解决了错误的问题。只需在每个字段前面写上pub 即可。重复代码是不好的,因为以后对代码的更改很容易出错——你可能会错过其中一个重复。这不是在每个字段名称前写pub 的问题。即使您决定稍后更改此设置,也几乎没有出错的风险。
  • @PetrusTheron,编写这样的派生可能是一个板条箱大小的工作。要获得有关生成此类方法的灵感,您可以查看getset crate,它能够为您生成公共 getter 和 setter。
  • @PetrusTheron 您可以在编辑器中使用多个光标或键盘宏来轻松地在每行前面添加pub,我认为这是正确的解决方案。在这里使用宏会使代码库的新手更难阅读代码,我相信这就是人们投票反对的原因。如果你决定无论如何都要使用宏,你可以从(struct $name:ident { $($field:ident : $type:ty,)* }) => { pub struct $name { $(pub $field: $type,)* } } 之类的规则开始,并根据需要对其进行细化以支持通用参数和字段属性。

标签: struct rust public rust-macros


【解决方案1】:
macro_rules! pub_struct {
    ($name:ident {$($field:ident: $t:ty,)*}) => {
        #[derive(Debug, Clone, PartialEq)] // ewww
        pub struct $name {
            $(pub $field: $t),*
        }
    }
}

不幸的是,derive 可能只应用于结构、枚举和联合,所以我不知道如何将它们提升给调用者。

用法:

pub_struct!(Foo {
    a: i32,
    b: f64,
});

如果我不需要括号和分号就好了,即如果 Rust 支持阅读器宏。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-09-09
  • 2020-12-04
  • 2017-12-09
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 2013-08-10
  • 2017-05-08
相关资源
最近更新 更多