有什么方法可以将匹配语句的主体与Rust宏进行匹配?

时间:2018-09-22 18:20:11

标签: macros rust

我有这样的想法:

macro_rules! mymatch {
   ($obj:ident, ($matcher:tt => $result:tt),*) => {
       match $obj {
           $matcher
       },
   }
}

mymatch! {
    x,
    10 => "Ten",
    n if n < 5 => "Less than 5"
}

我不想重新实现match语句,但是我想在任一侧添加其他内容。但是,我不知道如何搭配 匹配语句的内容。

1 个答案:

答案 0 :(得分:0)

语法有些错误。如果要匹配重复的模式,则需要以Set FirstPlace = Range("A2:A8").Find(what:=Largest, LookAt:=xlWhole) Set LastPlace = Range("A2:A8").Find(what:=Smallest, LookAt:=xlWhole) 开始分组,如下所示:$

接下来,由于任何表达式都可以匹配,因此您可能希望匹配的标识符不仅仅是标识符,因此请将其更改为$($matcher:tt => $result:tt),*。在expr的左侧,您需要一个=>(模式),而不是pat。令牌树是通用树,但例如,在tt中将匹配5个单独的令牌-n if n < 5nifn,{{1} }-而您通常只会在其他方法无效的情况下才使用该方法。结果也一样-这也应该是<(表达式)。

暂时忽略5防护,您可以匹配以下内容:

expr

具有以下宏:

if < 5

后卫很烦人,因为它们是可选的,但是my_match! { x, 10 => "Ten", _ => "something else" } 量词尚不稳定。取而代之的是,您必须使用macro_rules! my_match { ($obj:expr, $($matcher:pat => $result:expr),*) => { match $obj { $($matcher => $result),* } } } (0或更多),即使它在技术上比您需要的更多。

然后是完整的宏:

?

并支持此用法:

*

块也是macro_rules! my_match { ($obj:expr, $($matcher:pat $(if $pred:expr)* => $result:expr),*) => { match $obj { $($matcher $(if $pred)* => $result),* } } } ,所以这也是有效的:

let x = 7;
let s = my_match! {
    x,
    10 => "Ten",
    n if x < 5 => "Less than 5",
    _ => "something else"
};
println!("s = {:?}", s); // "Something else"