【问题标题】:Possible to derive attributes *after* a struct declaration?可以在 * 结构声明之后派生属性吗?
【发布时间】:2017-03-17 01:00:35
【问题描述】:

我正在使用宏来扩展原始结构:

pub struct MyTypedNumber(pub u32);
struct_impl_my_features!(MyTypedNumber);

struct_impl_my_features 宏可以实现MyTypedNumber 的功能和特征,但是在某些情况下它对使用#[derive(PartialEq, Eq)] 很有用 - 例如。

是否可以在结构已经声明后使用#[derive(...)]?

另一种方法是将结构定义作为item 参数传递给宏:

struct_impl_my_features!(
    pub struct MyTypedNumber(pub u32);,
    MyTypedNumber
);

这行得通,所以它可能是最好的选择,虽然它相当笨重并且意味着声明和宏扩展必须放在一起。

见this complete example,宏被称为struct_bitflag_impl(第二个例子)。


我通过手动实现PartialEq 和Eq 来解决这个问题,但是我遇到了Rust 需要 #[derive(...)] 用作match 语句中的常量的情况:

= warning: this was previously accepted by the compiler but is being phased out;
  it will become a hard error in a future release!
= note: for more information,
  see RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>

【问题讨论】:

  • 你能提供一个完整的例子吗? MyTypedNumber 与 MyTypedInt 有什么关系?
  • MyTypedInt 不小心留下,已更正 - 添加了完整示例的链接。
  • Derive 不会做任何神奇的事情。您应该能够手动执行与它完全相同的实现。您能否提供您认为需要派生的示例?
  • @paholg,这也是我所期望的,在大多数情况下也是如此,但是 Rust 编译器不赞成对非派生相等性的支持,请参阅:RFC 1445。

标签: macros rust


【解决方案1】:

您提供的“完整示例”链接确实显示了具有宏前缀属性的示例(请参阅第二个宏)。

    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
    $struct_p_def

但是,如果您希望能够为每个结构提供派生属性(例如,只有部分结构需要派生PartialEq),您可以在第二个@987654323 的第一部分传递派生表达式@ 示例——这些属性被认为是 item 宏形式的一部分。例如,

struct_impl_my_features!(
    #[derive(PartialEq, Eq)]
    pub struct MyTypedNumber(pub u32);,
    MyTypedNumber
);

更新

抱歉,我没有回答您的主要问题;据我所知,这是不可能的。但是,如果您主要关心的是笨重,并且您的结构都是相似的形式,您可以通过将其添加到宏的顶部来使您的宏调用更好:

($x:ident ( $($v:tt)* ) ) => {
    struct_impl_my_features!(pub struct $x( $($v)* );, $x)
};

然后这样称呼它:

struct_impl_my_features!(MyTypedNumber(pub u32));

【讨论】:

  • 我在询问后更新了从这个问题链接的第二个宏示例。即便如此,在定义结构后使用派生的能力还是很有用的,因为将结构定义传递给宏有点麻烦。更新了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 2016-04-26
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
相关资源
最近更新 更多