Function 定义将参数传递给函数的宏

Function 定义将参数传递给函数的宏,function,parameters,rust,macros,Function,Parameters,Rust,Macros,这是一个后续行动。我正在尝试编写一个宏调用。例如: fn add(x:u32, y:u32) -> u32 { x + y } let params: [u32; 2] = [2 ,3]; assert_eq!(call!(&add, params), 5); 对于静态数量的参数,宏很容易: macro_rules! call { ($function:expr, $params:expr) => { $function($params[0

这是一个后续行动。我正在尝试编写一个宏
调用。例如:

fn add(x:u32, y:u32) -> u32 { x + y }
let params: [u32; 2] = [2 ,3];
assert_eq!(call!(&add, params), 5); 
对于静态数量的参数,宏很容易:

macro_rules! call {    
    ($function:expr, $params:expr) => {
        $function($params[0], $params[1])
    };
}
我不知道如何使它在数量可变的参数下工作。我尝试了一些方法,但都遇到了以下两个问题之一:

  • 我尝试在宏之间传递不完整的代码片段,如
    $params[0],
    ,这是不允许的
  • 我尝试匹配长度并获得
    预期参数
    错误

  • 宏的问题是它们没有任何类型信息,您需要知道函数需要多少参数,或者数组的长度(并假设两者相等)。因此,如果你想纯粹用宏来实现这一点,你必须明确地给出这些信息,例如,
    call!(&add,参数,2)

    然而,你可以用traits来解决这个问题,因为它们确实有类型信息。您可以创建一个trait
    FnExpandArgs

    //用于调用具有参数列表的函数的助手特性。
    
    对于args

    Hm,这是一个可能的解决方案。不是最漂亮的,但它可以工作。基本上,在宏调用时,我们将发送一些宏可以处理和推断适当函数调用的参数

    macro_rules! call {    
        ($function:expr, 1, $params:expr) => {
            $function($params[0])
        };
        ($function:expr, 2, $params:expr) => {
            $function($params[0], $params[1])
        };
        ($function:expr, 3, $params:expr) => {
            $function($params[0], $params[1], $params[2])
        };
    }
    
    fn main(){
        fn add(x:u32, y:u32) -> u32 { x + y }
        fn incr(x:u32) -> u32 { x + 1 }
        let params1: [u32; 1] = [2];
        let mut params2: [u32; 2] = [2,3];
        assert_eq!(call!(&incr, 1, params1), 3);
        assert_eq!(call!(&add, 2, params2), 5);
        params2[0]=4;
        assert_eq!(call!(&add, 2, params2), 7);
    }
    

    我假设您需要显式地将数组的长度作为参数传递给宏。宏只能作为您可以自己插入的代码的简写。考虑如何为每个长度的PARAMs编写这些代码,然后计算如何生成一个宏来包含所有这些宏。详细说明是的,但是在使用键盘宏的Emacs中很容易实现。