如何解决使用Rust宏简化`match`
有很多问题函数(数百个),每个函数可能具有不同的类型。对于每个问题,我想运行一个run_question
函数,该函数显示该函数花费了多长时间,并输出了它的输出。
我正在尝试使用Rust宏缩短以下match
表达式(写run_question
一百次确实会使代码相当长):
fn run_question<T: std::fmt::Display>(question_func: fn() -> T) {
let begin = Instant::now();
let output: T = question_func();
let elapsed_secs = begin.elapsed().as_micros() as f32 / 1e6;
println!("{}",output);
println!("{:.6}s taken",elapsed_secs);
}
fn q1() -> u8 { /* ... */ }
fn q2() -> u32 { /* ... */ }
fn q3() -> u64 { /* ... */ }
fn q4() -> String { /* ... */ }
fn main() {
// ...
match question_num {
1 => run_question(q1),2 => run_question(q2),3 => run_question(q3),4 => run_question(q4),_ => {
println!("Question doesn't exist.");
},}
}
我没有编写宏的经验,并尝试了以下无法正常工作的宏。它给出了错误:
error: variable 'question_num' is still repeating at this depth
我也很困惑如何打印Question doesn't exist.
作为默认情况。
#[macro_export]
macro_rules! run_questions {
( $chosen_question: expr,$( $question_num: expr,$question_mod: expr ),* ) => {
{
if $chosen_question == $question_num {
run_question($question_mod::solve);
}
}
};
}
我想使用它的方式是(或任何简短的方法也可以):
run_questions!(question_num,1,q1,2,q2,3,q3,4,q4);
我读了Rust的书,但是并没有那么多的宏示例。
我将如何去做?
解决方法
我只复制了if
条语句,而不是许多match
条语句
对所有可用分支重复$( ... )*
。
它的行为似乎类似于广泛的match
表达式。
macro_rules! run_questions {
( $chosen_question: expr,$( $question_num: expr,$question_mod: expr ),* ) => {
match $chosen_question {
$($question_num => run_question($question_mod),)*
_ => {
println!("Question doesn't exist.");
}
}
};
}
,
错误消息说明:
macro_rules! run_questions {
($chosen_question: expr,$($question_num: expr,$question_mod: expr),*) => {{
在上述模式中,您使用*
运算符重复了一次,该运算符涉及变量$question_num
和$question_mod
if $chosen_question == $question_num {
run_question($question_mod::solve);
}
在相应的代码中,您不能直接使用$question_num
和$question_mod
:由于重复了它们,因此它们可能具有多个值,并且编译器应在此处使用哪个值?相反,您需要告诉编译器重复使用这些变量的代码块。这是通过用$()
包围重复的代码块并添加*
运算符来完成的:
$(if $chosen_question == $question_num {
run_question($question_mod::solve);
})*
尽管@ prog-fh的答案指出,最好在宏中使用match
,与直接代码相同:
match $chosen_question {
$($question_num => run_question ($question_mod::solve),)*
_ => println!("Question doesn't exist.")
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。