如何将包含多个项目的宏传递给宏?

ide*_*n42 5 macros rust

鉴于这个扩展多个项目的简单宏,这怎么能将宏作为参数呢?

macro_rules! print_structs {
    ($($t:ty)*) => ($(
        println!("{:?}", TypeId::of::<$t>());
    )*)
}

// expands one println per type!
print_structs! { i8 i16 usize String }
Run Code Online (Sandbox Code Playgroud)

如何传入预定义的宏类型?

非工作宏示例:

macro_rules! some_types {
    () => {
        i8 i16 usize String
    }
}

print_structs! { some_types!() }
Run Code Online (Sandbox Code Playgroud)

参见play.rust-lang.org示例,取消注释UNCOMMENT TO TEST行以查看问题。

给出错误: macro expansion ignores token `i16` and any following


我还尝试将列表放在要包含的文件中,例如:

print_structs! {
    include!("some_types.in")
}
Run Code Online (Sandbox Code Playgroud)

...但是这会产生一个错误: expected type, found `include!("../struct_list.rs")`

ide*_*n42 5

从这一点来看,似乎不可能使用宏或 来扩展宏内的列表include

尽管代码生成是一个选项,但它涉及相当多,因此将其排除在这个答案之外。

通过交换宏使用可以获得类似的功能,而不是将列表传递到宏中,而是将宏名称传递到用列表扩展它的通用宏中。

这是一个工作示例:

macro_rules! print_structs {
    ($($t:ty)*) => ($(
        println!("{:?}", ::std::any::TypeId::of::<$t>());
    )*)
}

macro_rules! apply_macro_to_structs {
    ($macro_id:ident) => {
        $macro_id! {
            i8 i16 usize String
        }
    }
}

fn test_a() {
    // expands one println per type!
    print_structs! { i8 i16 usize String }
}

fn test_b() {
    // expand using a macro
    apply_macro_to_structs!(print_structs);

}

fn main() {
    test_a();
    test_b();
}
Run Code Online (Sandbox Code Playgroud)