首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Rust宏来简化“match`”

使用Rust宏来简化“match`”
EN

Stack Overflow用户
提问于 2020-09-17 22:38:16
回答 2查看 87关注 0票数 1

有许多问题函数(数百个),每个问题函数可能有不同的类型。对于每个问题,我要运行一个run_question函数,该函数显示该函数花费了多长时间,并打印它的输出。

我正在尝试用一个Rust宏来缩短下面的match表达式(编写100次run_question确实会使代码相当长):

代码语言:javascript
复制
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.");
    },
  }
}

我没有编写宏的经验,并尝试了以下不完全有效的方法。它会给出错误:

代码语言:javascript
复制
error: variable 'question_num' is still repeating at this depth

我也很难理解如何将Question doesn't exist.打印为默认情况。

代码语言:javascript
复制
#[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);
      }
    }
  };
}

我想使用它的方式是(或者任何简短的东西也可以):

代码语言:javascript
复制
run_questions!(question_num, 1, q1, 2, q2, 3, q3, 4, q4);

我读过一点Rust这本书,但是宏的例子并不多。

我该怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-17 23:23:27

我没有使用许多if语句,而是使用重复的$( ... )*为所有可用分支复制了match语句。它的行为似乎类似于扩展的match表达式。

代码语言:javascript
复制
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.");
          }
        }
    };
}
票数 5
EN

Stack Overflow用户

发布于 2020-09-18 15:21:20

错误消息说明:

代码语言:javascript
复制
macro_rules! run_questions {
    ($chosen_question: expr, $($question_num: expr, $question_mod: expr),*) => {{

在上面的模式中,重复使用涉及变量$question_num$question_mod*运算符

代码语言:javascript
复制
        if $chosen_question == $question_num {
            run_question($question_mod::solve);
        }

在相应的代码中,您不能直接使用$question_num$question_mod:因为它们是重复的,所以它们可能有多个值,编译器应该在这里使用哪一个?相反,您需要告诉编译器重复使用这些变量的代码块。这是通过使用$()包围重复的代码块并添加*运算符来完成的:

代码语言:javascript
复制
        $(if $chosen_question == $question_num {
            run_question($question_mod::solve);
        })*

尽管正如@prog-fh的答案所指出的,最好在宏中使用match,与直接代码中的相同:

代码语言:javascript
复制
match $chosen_question {
    $($question_num => run_question ($question_mod::solve),)*
    _ => println!("Question doesn't exist.")
};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63940446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档