macros - 如何使用宏从函数定义集合开始创建函数名称数组?

标签 macros rust

我想在宏中创建一个数组来转换如下内容:

let array = create_array!(
    fn test() -> i32 { }
    fn test1() { }
);

进入

let array = [test, test1];

我试过这个:

macro_rules! create_array {
    () => {
    };
    (fn $func_name:ident () -> $return_type:ty $block:block $($rest:tt)*) => {
        $func_name,
        create_array!($($rest)*);
    };
    (fn $func_name:ident () $block:block $($rest:tt)*) => {
        $func_name,
        create_array!($($rest)*);
    };
}

但失败并出现以下错误:

error: macro expansion ignores token `,` and any following
  --> src/main.rs:11:19
   |
11 |         $func_name,
   |                   ^
   |
note: caused by the macro expansion here; the usage of `create_array!` is likely invalid in expression context
  --> src/main.rs:27:18
   |
27 |     let array = [create_array!(
   |

我也试过这个:

macro_rules! create_array {
    ($(fn $func_name:ident () $( -> $return_type:ty )* $block:block)*) => {
        [$($func_name),*]
    };
}

但它失败了:

error: local ambiguity: multiple parsing options: built-in NTs block ('block') or 1 other option.
  --> src/main.rs:22:19
   |
22 |         fn test() -> i32 { }
   |

那么在这种情况下我该如何创建一个数组呢?

最佳答案

从 Rust 1.20 开始,->$:block 的解析歧义已得到解决,因此您尝试的第二个版本现在可以按预期工作。

macro_rules! create_array {
    ($(fn $func_name:ident () $(-> $return_type:ty)* $block:block)*) => {
        [$($func_name),*]
    };
}

fn main() {
    let test = "TEST";
    let test1 = "TEST1";

    let array = create_array! {
        fn test() -> i32 {}
        fn test1() {}
    };

    println!("{:?}", array);
}

关于macros - 如何使用宏从函数定义集合开始创建函数名称数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39986539/

相关文章:

c - 宏 c 编程 #define min(a,b) (a < b ? a : b)

macros - 困难的boo语法宏

c - Flex 和 Bison,检测宏语句(新手)

generics - 实现不只是 impl Foo<T> 是否有技术原因?

rust - 从 HashSet 中获取具有最低值的元素?

c - "@"在 C/C++ 的宏中意味着什么?

c - "Local"C 中的标签和跳转表实现

azure - 如何在 Rust 中解码 Azure JWT token 以在我的应用程序中使用有效负载

rust - 如何使用 nom 吞噬字符串直到分隔符或结尾?

rust - 如何将两个 u8 原语转换为 u16 原语?