【发布时间】:2018-04-24 18:25:53
【问题描述】:
我需要一个可以调用具有不同数量参数的函数的宏,或者一个可以从其(重复)参数生成有效参数列表的宏。
我可以明确地提供有关宏参数数量的信息,但我不知道如何为函数生成参数列表 - 我总是偶然发现宏返回表达式而不是令牌树。
我做了以下playground example:
macro_rules! call (
($f: expr, $($params:tt)*) => {
$f(make_params!($($params:tt)*))
};
);
macro_rules! make_params {
() => {};
(I $($params: tt)*) => {
1, make_params!($($params:tt)*)
};
}
fn foo(a: i32, b: i32, c: i32) {
println!("foo: {} {} {}", a, b, c);
}
fn bar(a: i32, b: i32) {
println!("bar: {} {}", a, b);
}
fn main() {
call!(foo, I I I);
call!(bar, I I);
}
编译器抱怨如下:
error: macro expansion ignores token `,` and any following
--> src/main.rs:10:10
|
10 | 1, make_params!($($params:tt)*)
| ^
|
note: caused by the macro expansion here; the usage of `make_params!` is likely invalid in expression context
--> src/main.rs:3:12
|
3 | $f(make_params!($($params:tt)*))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
如何将make_params! 的返回视为令牌流(或其他)而不是表达式?
我的真实用例比这个玩具示例要复杂一些。我的函数有多种参数类型,它们以不同的方式构造。就我而言,只制作宏 call1、call2!、... 似乎不是一个好的解决方案,因为我需要 call_IIOOI、call_IIIO 等类似的东西。
【问题讨论】:
-
宏必须扩展为有效的 AST 元素。
1, foo不是有效的 AST 元素。 -
@mcarton 谢谢!哦,好吧......所以没有直接的方法来构造参数列表,你看到其他解决方案了吗?