可以在*结构声明之后派生属性吗?

ide*_*n42 5 macros rust

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

pub struct MyTypedNumber(pub u32);
struct_impl_my_features!(MyTypedNumber);
Run Code Online (Sandbox Code Playgroud)

struct_impl_my_features宏可以实现的功能和特性MyTypedNumber,但是有这样的情况,它的使用非常有用#[derive(PartialEq, Eq)]-例如。

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

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

struct_impl_my_features!(
    pub struct MyTypedNumber(pub u32);,
    MyTypedNumber
);
Run Code Online (Sandbox Code Playgroud)

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

看到这个完整的例子,宏被调用struct_bitflag_impl(第二个例子)。


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

pub struct MyTypedNumber(pub u32);
struct_impl_my_features!(MyTypedNumber);
Run Code Online (Sandbox Code Playgroud)

Jac*_*own 0

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

    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
    $struct_p_def
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望能够为每个结构提供导出属性(例如,只有某些结构需要导出PartialEq),则可以在第二个示例的第一部分中传递导出表达式struct_impl_my_features!- 属性被视为宏观item形式。例如,

struct_impl_my_features!(
    #[derive(PartialEq, Eq)]
    pub struct MyTypedNumber(pub u32);,
    MyTypedNumber
);
Run Code Online (Sandbox Code Playgroud)

更新

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

($x:ident ( $($v:tt)* ) ) => {
    struct_impl_my_features!(pub struct $x( $($v)* );, $x)
};
Run Code Online (Sandbox Code Playgroud)

然后这样称呼它:

struct_impl_my_features!(MyTypedNumber(pub u32));
Run Code Online (Sandbox Code Playgroud)