【问题标题】:How to pass a macro containing multiple items into a macro?如何将包含多个项目的宏传递给宏?
【发布时间】:2017-02-08 07:27:41
【问题描述】:

考虑到这个扩展多个项目的简单宏,它怎么能将宏作为参数?

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

// expands one println per type!
print_structs! { i8 i16 usize String }

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

非工作宏示例:

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

print_structs! { some_types!() }

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

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


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

print_structs! {
    include!("some_types.in")
}

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

【问题讨论】:

    标签: macros rust


    【解决方案1】:

    从调查来看,似乎无法使用宏或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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 2012-02-15
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多