Rust宏:调用依赖于表达式的函数
我有三个不同的函数,我想根据宏参数调用其中一个。这个参数应该经过预处理,这就是为什么我认为我需要将它写成Rust宏:调用依赖于表达式的函数,rust,rust-macros,Rust,Rust Macros,我有三个不同的函数,我想根据宏参数调用其中一个。这个参数应该经过预处理,这就是为什么我认为我需要将它写成expr。然而,我似乎找不到一种方法来区分宏中expr的不同情况。这是我的密码: fn func_100(){ println!("Func 100!"); } fn func_200(){ println!("Func 200!"); } fn func_300(){ println!("Func 300!"); } macro_rules! generate_fu
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
表达式调用不同的函数?您可以通过调用cargo+nightly rustc--profile=check--Zunstable options--pretty=expanded
或使用
fn f1(){
{
::std::io::_打印(::std::fmt::Arguments::new_v1)(
&[“”,“\n”],
&匹配(&(100/100),){
(arg0,)=>[::std::fmt::ArgumentV1::new(arg0,::std::fmt::Debug::fmt)],
},
));
};
();
}
您可以看到最后一个()代码>应该是func_100()
这是因为在类型为($number:expr)
的generate\u func\u call
中没有令牌规则,即没有与扩展匹配的规则。这是因为在函数中,$number
不会被100
替换。宏只是根据它接收到的数据创建更多的代码,它不尝试评估任何内容
将代码更改为:
macro\u规则!生成函数调用{
($number:expr)=>{
匹配$number{
100=>func_100(),
200=>func_200(),
300=>func_300(),
_ => (),
}
};
}
最后是()代码>更改为:
匹配300{
100=>func_100(),
200=>func_200(),
300=>func_300(),
_ => (),
};
您不必担心额外的跳转语句之类的问题,它会得到优化,因为300
是编译时常量。它只是变成了func_300()
看起来它根本不受支持
一种可能的解决方法是匹配第一个宏中的文本,如下所示。尽管这只是引入了更多的代码重复
将来可能会使用类似于此的const fn
功能来实现这一点。但你得等一等
现在我建议在运行时使用常规的match
匹配值,因为Rust编译器在优化方面非常好,所以如果在if
表达式中使用常量,它将为您消除这一点,因此对运行时没有影响。非常相关(如果不是dup):可能重复