簡體   English   中英

將宏 arguments 傳遞給其他宏

[英]pass macro arguments to other macro

我是 rust 的新手。 我正在嘗試創建一個宏,它需要一個緩沖區,然后從中解碼一些數據並創建變量的給定列表。 如果發生錯誤,那么它應該打印錯誤並繼續,因為我將在接收緩沖區的循環中調用它。 像這樣的東西: -

for bin_ref in bufs {

   extract!( bin_ref anime &str episodes u32 season u32);

   //if everything goes ok then do some cool stuff with
   //above variables otherwise take next buf_ref    
}

我怎樣才能做到這一點? 因此,我采用了這種方法:-

#[macro_export]
macro_rules! extract {

    ( $buf:ident $($var:ident $typ:ty),* ) => {
        $(
            ext_type!( $buf $var $typ );
        )*
    };
}

#[macro_export]
macro_rules! ext_type {
    ( $buf:ident $var:ident &str ) => {

        let mut $var : &str = ""; //some string specific function
        println!("doing cool things with '{}' which is string ",$var);        

    };
    ( $buf:ident $var:ident u32 ) => {
        let mut $var : u32 = 34; //some u32 specific function
        println!("doing cool things with '{}' which is u32",$var);
    }
}

我有以下測試 function:-

fn macro_test() {

    let mut bin_ref : &[u8] = &[0u8;100];

    ext_type!(bin_ref anime &str); // works
    ext_type!(bin_ref episodes u32 ); // works

    extract!( bin_ref username &str, password &str ); // does not work. why ??
}

當我編譯這個時,我得到以下錯誤: -

error: no rules expected the token `&str`
  --> src/easycode.rs:11:34
   |
11 |             ext_type!( $buf $var $typ );
   |                                  ^^^^ no rules expected this token in macro call
...
19 | macro_rules! ext_type {
   | --------------------- when calling this macro
...
48 |     extract!( bin_ref username &str, password &str );
   |     ------------------------------------------------- in this macro invocation

為什么我不能只將$typ傳遞給ext_type! 宏? 從代碼調用時它可以工作

ext_type! 宏的規則最后需要文字標記&stru32 這些文字標記無法匹配extract!中的匹配片段$typ:ty . 為了成功地將文字標記與匹配的片段匹配, 它必須是ttidentlifetime

在這種情況下,唯一可行的選項是tt ,簡單地說,就是一個解析器令牌。 但是,一種類型通常由多個標記組成; &str ,它由兩個標記&str組成。 因此,我們必須使用重復來完全捕獲具有tt s 的類型: $($typ:tt)+會做得很好。

然而,對tt使用無限重復是有代價的——一個tt將匹配幾乎所有內容,所以簡單地將$typ:ty替換為$($typ:tt)+是行不通的,因為$typ重復將捕獲所有內容,直到在宏調用結束時,為了防止這種情況發生,我們必須在宏規則匹配器中划定類型標記樹,以阻止它消耗所有內容。 以使調用稍微冗長為代價,將括號中的重復括起來將為我們提供很好的服務,並停止與我們想要的完全匹配的令牌樹。 修改后的宏如下所示:

#[macro_export]
macro_rules! extract {
    ( $buf:ident $($var:ident ($($typ:tt)+)),* ) => {
        $(
            ext_type!( $buf $var $($typ)+);
        )*
    };
}

注意匹配器中的$typ:ty替換為($($typ:tt)+) (這是一個用括號括起來的標記樹重復),以及轉錄器中的$typ替換為$($typ)+ .

宏規則調用如下:

extract!(bin_ref username (&str), password (&str), id (u32));

Rust游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM