【问题标题】:Macro match arm pattern "no rules expected the token `if`"宏匹配臂模式“没有规则需要令牌`if`”
【发布时间】:2021-01-01 15:54:34
【问题描述】:

所以我有这个宏用于匹配 Box<dyn error::Error> 与多种错误类型

#[macro_export]
macro_rules! dynmatch {
    ($e:expr, $(type $ty:ty {$(arm $pat:pat => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
        $(
            if let Some(e) = $e.downcast_ref::<$ty>() {
                match e {
                    $(
                        $pat => {$result}
                    )*
                    _ => $any
                }
            } else
        )*
        {$end}
    );
}

在我尝试添加 match gaurds 之前它工作正常。当我尝试在模式中使用“if”语句时,它给了我错误no rules expected the token 'if'

let _i = match example(2) {
    Ok(i) => i,
    Err(e) => {
        dynmatch!(e,                                                            
            type ExampleError1 {                                                
                arm ExampleError1::ThisError(2) => panic!("it was 2!"),  
                _ => panic!("{}",e)                                             
            },
            type ExampleError2 {
                arm ExampleError2::ThatError(8) => panic!("it was 8!"),
                arm ExampleError2::ThatError(9..=11) => 10,
                _ => panic!("{}",e)
            }, 
            type std::io::Error {                                               
                arm i if i.kind() == std::io::ErrorKind::NotFound => panic!("not found"), //ERROR no rules expected the token `if`
                _ => panic!("{}", e)
            },
            _ => panic!("{}",e)                                                 
        )
    }
};

有什么方法可以在我的模式匹配中使用匹配保护而不会出现令牌错误?

【问题讨论】:

    标签: error-handling rust macros pattern-matching


    【解决方案1】:

    当然,尽管我花了大约一个小时寻找解决方案,但在我发布此问题后,我立即找到了答案。

    正确的宏如下所示:

    #[macro_export]
    macro_rules! dynmatch {
        ($e:expr, $(type $ty:ty {$(arm $( $pattern:pat )|+ $( if $guard: expr )? => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
            $(
                if let Some(e) = $e.downcast_ref::<$ty>() {
                    match e {
                        $(
                            $( $pattern )|+ $( if $guard )? => {$result}
                        )*
                        _ => $any
                    }
                } else
            )*
            {$end}
        );
    }
    

    归功于 matches! source 第 244-251 行的 rust

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      相关资源
      最近更新 更多