代码之家  ›  专栏  ›  技术社区  ›  bbarker

为什么调用以下宏时需要分号?

  •  0
  • bbarker  · 技术社区  · 5 年前

    我正试图写一个宏来在人造丝之间切换 par_iter 和性病 iter 取决于构建特性(可能是我自己,因为我还没有读太多关于宏的书)。在这里处理宏似乎比处理函数要好一些,因为函数可能需要一些相对复杂的类型才能工作;此外,如果我想在构建特性中添加更多关于如何运行迭代器的变体,那么宏在将来可能会保持更灵活。

    #[macro_export]
    macro_rules! par_iter {
        ($($tokens:tt)*) => {
          #[cfg(feature = "threaded")]
          $($tokens)*.par_iter()
          #[cfg(not(feature = "threaded"))]
          $($tokens)*.iter()
        }
    }
    

    error: macro expansion ignores token `b_slice` and any following
       --> src/util.rs:28:8                                                                      
        | 
    28  |       $($tokens)*.iter();
        |        ^^^^^^^^^
        |                                                                                        
       ::: src/counting.rs:219:9                                                                 
        |
    219 |         par_iter!(b_slice).map(WordCount::from)                                                                                                                                     
        |         ------------------- help: you might be missing a semicolon here: `;`
        |         |                                                                              
        |         caused by the macro expansion here
        |
        = note: the usage of `par_iter!` is likely invalid in expression context
    

    虽然我不知道第一个错误,但我很好奇为什么 ;

    1 回复  |  直到 5 年前
        1
  •  1
  •   vallentin Remi    5 年前

    这基本上归结为,你不允许 attributes 在这样的表达式中,例如,以下内容无效:

    b_slice.iter()
        #[cfg(not(feature = "threaded"))]
        .map(|x| x)
        .collect();
    

    请注意双精度 {{ }} block

    #[macro_export]
    macro_rules! par_iter {
        ($($tokens:tt)*) => {{
            #[cfg(feature = "threaded")]
            let it = $($tokens)*.par_iter();
            #[cfg(not(feature = "threaded"))]
            let it = $($tokens)*.iter();
            it
        }};
    }
    

    或者,也可以将其拆分为两个宏,如下所示:

    #[cfg(feature = "threaded")]
    #[macro_export]
    macro_rules! par_iter {
        ($($tokens:tt)*) => {
            $($tokens)*.par_iter()
        }
    }
    
    #[cfg(not(feature = "threaded"))]
    #[macro_export]
    macro_rules! par_iter {
        ($($tokens:tt)*) => {
            $($tokens)*.iter()
        }
    }
    
    推荐文章