首页 > 解决方案 > 有没有办法使用宏定义“匹配”标签?

问题描述

我的意思是,看代码

macro_rules! impls {
    () => {
        let a = "Hello, world!";
        println!("{}", match 7 {
            impls!{ 3 + 4, a }
            _ => unimplemented!()
        })
    };

    ($x:expr, $name:ident) => {
        ($x) => $name,
    }
}

fn main() {
    impls!{ }
}

正如我所想,impls!{ 3 + 4, a }应该是(3 + 4) => a,但事实并非如此。怎么了?编译器错误:

error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
  --> src/main.rs:6:13
   |
5  |             impls!{ 3 + 4, a }
   |                               - expected one of `=>`, `if`, or `|`
6  |             _ => unimplemented!()
   |             ^ unexpected token
...
16 |     impls!{ }
   |     --------- in this macro invocation
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

标签: rust

解决方案


这对于声明性宏是不可能的(可能是过程宏,我对这些宏的经验很少,所以我不知道):根据文档

宏可以扩展到表达式、语句、项目(包括特征、实现和外来项目)、类型或模式。

匹配臂本身并不是“Rust 构造”,它是表达式的子项(match由模式、可选的保护表达式和主体表达式组成)。

因此,它不能由声明性宏生成。


推荐阅读