Rust 的巨集

weixin_34320159發表於2017-08-01

首先, 我感覺 Rust 的巨集是非常強大的, 可以根據 match 有不同的實現,但是它也是極其讓人,起碼是讓我糾結的和費解的, 我希望能夠一點點的弄懂他

文件來看

// 定義巨集的語法
macro_rules! vec {
  // 這裡的 * 感覺是一種連續的匹配值
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            // $()*的語法在我看來就是一種迭代器,讓我們迭代所有的匹配結果
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

在一些複雜的巨集中, 甚至用到了一些遞迴的寫法
我們在 匹配的時候發現 匹配到的值後面有 :expr, 文件中也給出了一系列規則

ident: 識別符號,用來表示函式或變數名
expr: 表示式
block: 程式碼塊,用花括號包起來的多個語句
pat: 模式,普通模式匹配(非巨集本身的模式)中的模式,例如 Some(t), (3, 'a', _)
path: 路徑,注意這裡不是作業系統中的檔案路徑,而是用雙冒號分隔的限定名(qualified name),如 std::cmp::PartialOrd
tt: 單個語法樹
ty: 型別,語義層面的型別,如 i32, char
item: 條目,
meta: 元條目
stmt: 單條語句,如 let a = 42;

#[macro_use] 表示子模組的巨集可以被父模組呼叫
#[macro_export] 表示可以被其他的 crate 呼叫
$crate 在巨集中表示該模組

例項解析

error_chain 這個類庫就是一個使用巨集的範例,我們今天就來看一下
這個庫的主要功能就是通過簡單的設定,讓巨集來完成所有重複的程式碼

基本的實現就是 通過一步步的巨集的迭代,把需要的引數排序並且解析出來,之後再通過解析出來的引數,組合並且返回相應的程式碼塊,程式碼塊中已經把 錯誤型別, 錯誤文件, 錯誤程式碼 全部都自動組合好

相關文章