我有三个不同的函数,我想基于宏参数调用一个函数。该参数应该经过预处理,这就是为什么我认为我需要将其写为expr
的原因。但是,我似乎找不到一种方法来区分宏中expr
的不同情况。这是我的代码:
fn func_100(){
println!("Func 100!");
}
fn func_200(){
println!("Func 200!");
}
fn func_300(){
println!("Func 300!");
}
macro_rules! generate_func_call {
(100) => {
func_100();
};
(200) => {
func_200();
};
(300) => {
func_300();
}
}
macro_rules! generate_func_call_wrapper {
($func: ident, $number: expr) => {
fn $func(){
println!("{:?}", $number / 100);
generate_func_call!($number);
}
};
}
generate_func_call_wrapper!(f1,100);
generate_func_call_wrapper!(f2,200);
generate_func_call_wrapper!(f3,300);
fn main(){
f1();
}
会产生以下编译时错误:
generate_func_call!($number);
^^^^^^^ no rules expected this token in macro call
如何修复该程序,以便基于$number
表达式调用其他函数?
答案 0 :(得分:2)
您可以通过调用cargo +nightly rustc --profile=check -- -Zunstable-options --pretty=expanded
或使用cargo-expand
fn f1() {
{
::std::io::_print(::std::fmt::Arguments::new_v1(
&["", "\n"],
&match (&(100 / 100),) {
(arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Debug::fmt)],
},
));
};
();
}
您可以看到应该是();
的最后一个func_100()
这是因为在generate_func_call
类型的($number: expr)
中没有令牌规则,即没有与扩展匹配的规则。这是因为$number
并未像您在函数中所期望的那样被100
取代。宏只是根据收到的fragment types创建更多的锈代码,它不会尝试评估任何东西。
将代码更改为:
macro_rules! generate_func_call {
($number: expr) => {
match $number {
100 => func_100(),
200 => func_200(),
300 => func_300(),
_ => (),
}
};
}
最后();
更改为:
match 300 {
100 => func_100(),
200 => func_200(),
300 => func_300(),
_ => (),
};
答案 1 :(得分:0)
看起来根本不受支持。
Simmilar Issue #1 Simmilar Issue #2
一种可能的解决方法是与第一个宏中的文字匹配,例如在playground中。尽管这只会引入更多的代码重复。
将来,可能会使用playground中的const fn
功能来做到这一点。但是您必须等待feature to be implemented。
现在,我建议使用常规match
在运行时简单地将其值与之匹配。