【发布时间】:2017-03-19 10:47:32
【问题描述】:
我正在尝试构建一个可以使用函数调用列表 (test2()) 或标识符 (test3) 调用的宏:
invoke!(
["str1", "str2"]: i32 => test1(), test2(), test3, test4;
["str3", "str1"]: i32 => test1(), test3;
)
目前只支持函数调用:
invoke!(
["str1", "str2"]: i32 => test1(), test2();
["str3", "str1"]: i32 => test1();
)
原宏代码:
macro_rules! invoke {
( $([$($field:expr),*]: $vtype:ty => $($func:ident$args:tt),*; )+ ) => {
$(
let x = vec![$($field),*];
let y = vec![$($func$args),*];
println!("{:#?}: {:#?}", x, y)
)+
};
}
当我尝试将其更改为支持两种形式时:
macro_rules! invoke {
( $([$($field:expr),*]: $vtype:ty => $($func:ident$args:tt),* $($newfunc:ident),*; )+ ) => {
$(
let x = vec![$($field),*];
let y = vec![$($func$args),*];
let z: Vec<$vtype> = vec![$newfunc()];
println!("{:#?}: {:#?} [{:#?}]", x, y, z)
)+
};
}
我收到一个错误:
error: local ambiguity: multiple parsing options: built-in NTs ident ('func') or ident ('newfunc').
--> src/main.rs:15:34
|
15 | ["str1", "str2"]: i32 => test1(), test2(), test3, test4;
| ^^^^^
我知道可以通过:tt 构建这个宏,但我找不到方法。
【问题讨论】:
-
你能改变
invoke!的调用方式吗? -
@kennytm 它在代码中明确显示:
invoke!( ["str1", "str2"]: i32 => test1() test2(); ["str3", "str1"]: i32 => test1(); ) -
我在你的宏中发现了错误——即使你说的那个是有效的。另外,您能否展示一下您希望将您的第一个示例转换成什么?
-
@PeterHall 我不知道你怎么会出错。我添加了问题的链接,它是有效的代码示例。随着时间的推移,我添加了预期的样本。
-
@mrLSD 我的意思是,不是
invoke!(["str1"]: i32 => test1(), test2(), test3, test4),你能把语法改成invoke!(["str1"]: i32 => {test1() => test3, test2() => test4})吗?