是否可以在宏中嵌套结构声明以应用struct属性?

时间:2016-11-03 13:08:03

标签: macros rust

如果我们想概括地将#[derive(...)]应用于结构,在某些情况下将它包装在宏中会很有用。

非工作示例:

my_traits!(
    pub struct MyType(u32),
    MyType
);

my_traits可以在第一个参数前加上#[derive(...)],并使用第二个参数声明impl SomeTrait for $t {...}

声明实现没有任何问题,但是我没有设法使用宏来为struct声明添加属性前缀。

请参阅此问题,了解可以使用的示例:
Possible to derive attributes *after* a struct declaration?

2 个答案:

答案 0 :(得分:2)

#[derive(...)]置于宏中似乎工作正常:

#[derive(Eq,PartialEq,Debug)]
struct Foo(u32);

macro_rules! my_eq(
    ($name:ident) => {
        #[derive(Eq,PartialEq,Debug)]
        struct $name(u32);
    };
);

my_eq!(Bar);

fn main() {
    assert_eq!(Foo(3), Foo(3));
    assert!(Foo(3) != Foo(4));
    assert_eq!(Bar(3), Bar(3));
    assert!(Bar(3) != Bar(4));

}

Playground link

或者如果您想传递整个struct

macro_rules! my_eq(
    ($name:item) => {
        #[derive(Eq,PartialEq,Debug)]
        $name
    };
);

my_eq!(struct Bar(u32););

Playground

请注意,宏需要一个整个项目,因此需要在宏调用中使用分号(Foo{}结构不需要它,就像内联编写时一样。)

答案 1 :(得分:0)

这可以通过传递item来完成,感谢IRC上的@j_ey。

macro_rules! ideas {
    ($ty: item, $id: ident) => {
        #[derive(Debug)]
        $ty
        impl $id {
            fn doit(){}
        }
    }
}

ideas!(pub struct Foo(u32);, Foo);

fn main() {
    let f = Foo(1);
    println!("{:?}", f);
}